Hi I’m trying to test some standart C features various compiler and I found a difference between NVC and others(clang,gcc,msvc etc). NVC give different result. Below I give minimal code to reproduce this bug(maybe). normally gcc will call functions before the arithmetic operations then evaluate. but NVC call f2() then evalute mult and then call f1().
nvc:
%0 = call i32 @f2 () mustprogress, !dbg !147
%1 = mul i32 %0, 5, !dbg !147
%2 = call i32 @f1 () mustprogress, !dbg !147
%3 = add i32 %1, %2, !dbg !147
gcc:
call f1
mov ebx, eax
call f2
mov edx, eax
mov eax, edx
sal eax, 2
add eax, edx
add eax, ebx
mov esi, eax
Hi Demir,
Thanks for the post, but this isn’t a bug but undefined behavior in your code. The order in which functions are evaluated is not specified by the C standard and the compiler is free to choose either left-to-right or right-to-left.
From Order of evaluation - cppreference.com.
Order of evaluation of the operands of any C operator, including the order of evaluation of function arguments in a function-call expression, and the order of evaluation of the subexpressions within any expression is unspecified (except where noted below). The compiler will evaluate them in any order, and may choose another order when the same expression is evaluated again.
There is no concept of left-to-right or right-to-left evaluation in C, which is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3()
is parsed as (f1() + f2()) + f3()
due to left-to-right associativity of operator+, but the function call to f3
may be evaluated first, last, or between f1()
or f2()
at run time.
Hope this helps,
Mat
https://en.cppreference.com/w/c/language/operator_precedence
I didn’t catch evaluation page but there is a confusing operator precedence page says differently. I think this is a unspecified behaviour not undefined behaviour.