问题
As stated in this question: LLVM and GCC, different output 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;
}
The 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 the other question, someone answered that the order of evaluation of the parameters is not specified which is why the behavior is unspecified. However, if you go through the code very carefully, you can see that in fact the order of evaluation IS specified. The GCC compiler is evaluating x,increment(),MAX(x, increment())
from the printf()
method right-to-left, while the LLVM compiler is evaluating this code left-to-right. Does anyone know why this is the case? Shouldn't something like the order of evaluation of printf
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 properly or to have output that is accurate. The wacky output is intentional and so is the use of a silly macro like the one used in the code (MAX). I'm only trying to understand why there is such a big difference here, thanks!
回答1:
The evaluation order of function arguments isn't defined by the specification. Compilers are free to evaluate in whatever order they like. Just because a particular implementation happens to do it in a consistent way doesn't change the fact that two different implementations might have different behaviour.
If you want consistent output from different compilers, you need to write code that has well-defined behaviour according to the standard.
来源:https://stackoverflow.com/questions/25669493/c-why-does-llvm-evaluate-printf-left-to-right-when-gcc-evaluates-right-to-left