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

时间:2013-04-10 15:13:01

标签: c macos gcc compiler-construction llvm

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

代码:

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

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

2 个答案:

答案 0 :(得分:13)

参数的评估顺序未指定 defined 。所以这个:

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

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

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

答案 1 :(得分:-2)

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