LLVM和GCC,不同的输出相同的代码

这是一个示例代码,仅用于显示LLVM编译器和GCC的不同输出。 我想知道为什么? 答案应该很简单,但我看不到它。 (Xcode 4.6.1)

代码:

#include  #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输出:

 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 

GCC输出:

 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 

未定义参数的评估顺序。 所以这:

 printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment())); 

导致未定义的未指定行为 。 这就是为什么你在两个编译器上都有不同的结果。

另一个(潜在的)问题是: MAX – 它可能导致两次调用increment 。 避免使用这样的宏。

LLVM代码根据ANSI C生成正确的结果。如果您不希望每个print语句多次调用increment,请将返回值保存在变量中并使用它。 在心理上踩过代码,显示应该是增量返回47增量返回52增量返回57最大值50和47是57增量返回62增量返回67最大值50和62是72所以我最初的反应和研究代码是错误的,LLVM输出是正确的。 LLVM结果的原因是对于main中的每个print语句,增量被调用三次。 使代码打印合理输出的方法是保存变量中增量返回的值并打印变量,而不是另一个增量调用。 据我所知,结果的差异并不依赖于未定义的行为,而是依赖于与ANSI C的正确与错误的一致性。