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

霸气de小男生 提交于 2020-01-04 04:06:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!