返回信息流#include <stdio.h>
int main() {
unsigned int i;
printf("Hello!\n");
for (i=0; i<i+1; i++) {
}
printf("Goodbye!\n");
return 0;
}
保存成cuw.c
$ gcc -O3 -ocuw-O3 cuw.c
$ ./cuw-O3
Hello!
Goodbye!
$
下一段程序:
#include <stdio.h>
int main() {
int i;
printf("Hello!\n");
for (i=0; i<i+1; i++) {
}
printf("Goodbye!\n");
return 0;
}
保存成csw.c
$ gcc -O0 -ocsw-O0 csw.c
$ ./csw-O0
Hello!
Goodbye!
$ gcc -O3 -ocsw-O3 csw.c
$ ./csw-O3
Hello!
然后就死在那里了,可以用ctrl+c中断。
这是怎么回事?
这是一条镜像帖。来源:北邮人论坛 / cpp / #80075同步于 2014/6/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[C语言也惊喜]1:这两个程序有什么区别?为什么结果不同?
nuanyangyang
2014/6/3镜像同步5 回复
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
--占个座,肉眼看没看懂
手机看不全代码给跪了。。。
通过『我邮2.0』发布
汇编下发现,csw -O3 -O2 下L2循环是这样的:
.L2:
jmp .L2
而-O1下的循环是这样的
.L3:
movl %edx, %eax
.L2:
leal 1(%rax), %edx
cmpl %edx, %eax
jl .L3
movl $.LC1, %edi
call puts
movl $0, %eax
addq $8, %rsp
怀疑和-fstrict-overflow有关
-fstrict-overflow让编译器认为有符号数不会溢出,因而上述循环被编译成一个无限循环。
-fstrict-overflow
For example, a loop like
for (i = 1; i > 0; i *= 2)
is presumably intended to continue looping until i overflows. With -fstrict-overflow, the compiler may assume that signed overflow will not occur, and transform this into an infinite loop. -fstrict-overflow is turned on by default at -O2, and may be disabled via -fno-strict-overflow. The -Wstrict-overflow option may be used to warn about cases where the compiler assumes that signed overflow will not occur.