有如下代码:
int a, *b; a = 10; b = &a; printf("%d %d\n", ++a, --a);
加上 b= &a; 的输出:11 10
不加上 b = &a; 的输出:10 10
不加上的应该是`printf```的参数在进行运算前就确定了。
现在问题是:
为什么加上 b = &a; ,在 printf 中的自增 /自减运算就会在 printf 确定参数前先一步执行?
![]() | 1 xcstream 2019-12-17 06:26:23 +08:00 ![]() c 语言未定义的行为 编译器不同,结果也不同 |
![]() | 3 crc8 2019-12-17 09:43:30 +08:00 gcc 下输出是 10 10 和 10 9 |
4 azcvcza 2019-12-17 10:04:22 +08:00 c 语言的自增在前或者在后,语义都不一样。++a 是先对 a 做递增,再输出,a++则是先输出旧 a 再更新 a 的值。 一般还是写 a+=1 好一些 |
![]() | 5 xxdd 2019-12-17 10:07:56 +08:00 记得老早知乎的薛飞 擅长这个(狗头) |
![]() | 6 labubu 2019-12-17 10:39:30 +08:00 via Android 不同的编译器的参数入栈顺序不一样,gcc 好像从右往左 |
![]() | 7 summer20100514 2019-12-17 10:54:09 +08:00 确实和 3 楼一样的结果,应该是编译器的优化。gcc -S 看下汇编,是不一样的 |
![]() | 9 shiltian 2019-12-17 11:02:56 +08:00 我猜是因为两次 alias analysis 的结果不同导致 instruction reorder 的结果也不同,也正如楼上所说,由于这是未定义的行为,所以表现如何就真看编译器怎么做了。 BTW 在我的电脑上用 LLVM 两个结果都是 11 10,无论是 -O 几。 |
10 evilhero OP |
![]() | 11 InkStone 2019-12-17 11:08:27 +08:00 @evilhero C++ primer 上有很多*iter++的写法。其实只要你自己够熟悉,并且不要滥用,就没什么关系。 |
12 evilhero OP @tianshilei1992 谢谢解答,看来要多装几个编译器了 |
13 evilhero OP @InkStone 主要是只是&a 取了地址给 b,其他没有对 a 进行任何操作,结果竟然不一样,感觉好神奇 |
14 anonymous256 2019-12-17 13:16:33 +08:00 不是编译器问题! 你 google 搜这个关键词: sequence point, 就明白了. 写出这样的代码是不应该的. 你表达式的顺序是不确定的, 行为未定义. https://stackoverflow.com/questions/3575350/sequence-points-in-c https://en.wikipedia.org/wiki/Sequence_point |
15 evilhero OP @anonymous256 确实不应该这样写,但是试卷是就是这样… |