C“printf”Linux和Mac中的输出不同

时间:2015-11-23 08:08:57

标签: c linux macos printf

#include <stdio.h>
int main(void) {
        int i=1;
        printf("%d %d\n", i+=1, i);
        printf("%d %d\n", i, i+=1);
        return 0;
}

上面的代码显示了Linux和Mac中的不同输出。 在Linux中:( gcc版本4.9.2 20150212(Red Hat 4.9.2-6))

2 2
3 3

在Mac中:( Apple LLVM版本7.0.0(clang-700.0.57.2))

2 2
2 3

在Linux中,我尝试使用c11,c99,c89。但输出是一样的。所以我认为这不是C标准问题。

  1. 为什么会出现这种行为?
  2. 哪一个是正确的,为什么?

3 个答案:

答案 0 :(得分:2)

C参考不保证此计算顺序。这意味着每个编译器都可以按照它认为合适的顺序自由地执行它。出于这个原因(为了便于阅读),你应该避免以这种方式写作。

答案 1 :(得分:2)

评估这些语句的顺序由实现定义,并且不在C标准中保证。这使得此代码未定义行为。这意味着发生的任何事情都是有效的,也是无关紧要的,因为它确实是未定义的。

答案 2 :(得分:1)

以未定义的顺序评估参数,因此i+=1可以在i之前或之后发生。

这是未定义的,因为堆栈上元素的顺序可能不同,导致一些调用约定顺序的编译器比另一个慢。

这是一个可接受的标准,因为替代方案(将代码分开如下,导致更好的可读性(没有不确定性)。

 int i = 1, tmp1, tmp2;
 i+= 1;
 tmp1 = i;
 tmp2 = i;
 printf("%d %d\n", tmp1, tmp2 );
 tmp1 = i;
 i += 1;
 tmp2 = i;
 printf("%d %d\n", tmp1, tmp2 );