C: why does LLVM evaluate printf from left to right when GCC evaluates right to left?

As stated in this question: LLVM and GCC, different output of the same code , LLVM and GCC result in different output for the same code.

#include <stdio.h>

#define MAX(a,b) ( (a) > (b) ? (a) : (b) )

int increment() {
    static int i = 42;
    i += 5;
    printf("increment returns %d\n",i);
    return i;
}

int main( int argc, char ** argv ) {
    int x = 50;
    printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment()));
    printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment()));
    return 0;
}

      

LLVM output gives:

increment returns 47
increment returns 52
increment returns 57
max of 50 and 47 is 57
increment returns 62
increment returns 67
increment returns 72
max of 50 and 62 is 72

      

while the GCC output gives:

increment returns 47
increment returns 52
max of 50 and 52 is 50
increment returns 57
increment returns 62
increment returns 67
max of 50 and 67 is 62

      

Now, in another question, someone answered that the order of parameter evaluation is not specified, so the behavior is unspecified. However, if you read the code carefully, you will see that the order of evaluation is actually specified. The GCC compiler evaluates x,increment(),MAX(x, increment())

from printf()

right to left, while the LLVM compiler evaluates from left to right. Does anyone know why this is so? printf

Shouldn't something like the order of evaluation be clearly defined and the same for both compilers?

Also, I just want to clarify that this code is from a tutorial and is aimed at understanding how the C language works. Its purpose is not to be a program that works as expected or to have an accurate result. The unusual output is intentional, and therefore a silly macro is used, such as the one used in the (MAX) code. I'm just trying to figure out why there is such a big difference here, thanks!

+3


source to share


1 answer


The order in which function arguments are evaluated is not specified by the specification. Compilers are free to evaluate in any order. Just because a particular implementation does it sequentially does not change the fact that two different implementations may have different behavior.



If you want consistent output from different compilers, you need to write code that has well-defined behavior according to the standard.

+9


source







All Articles