有如下代码:
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 2
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
daimiaopeng 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
tianshilei1992 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 确实不应该这样写,但是试卷是就是这样…
|