我正在运行一些测试,以了解++ i和i ++如何转换为asm。我写了一个简单的:
int main()
{
int i;
for(i=0;i<1000000;++i);
return 0;
}
用gcc test.c -O0 -o test编译它,并用objdump -d test检查asm :
4004ed: 48 89 e5 mov %rsp,%rbp
4004f0: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) // i=0;
4004f7: eb 04 jmp 4004fd <main+0x11>
4004f9: 83 45 fc 01 addl $0x1,-0x4(%rbp) // ++i;
4004fd: 81 7d fc 3f 42 0f 00 cmpl $0xf423f,-0x4(%rbp) //
400504: 7e f3 jle 4004f9 <main+0xd> //i<1000000;
400506: b8 00 00 00 00 mov $0x0,%eax
40050b: 5d pop %rbp
40050c: c3 retq
到目前为止,一切都很好。奇怪的是(如果我正确理解了asm代码)是什么时候而不是i <1000000我写了i <10000000000。循环条件与i <10000000000的停止条件完全相同,转换为以下汇编代码:
4004ed: 48 89 e5 mov %rsp,%rbp
4004f0: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
4004f7: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004fb: eb fa jmp 4004f7 <main+0xb>
根据我的理解,这是一个无休止的循环,原因是:
for(i=0;;++i);
问题是,是否真的有可能将其编译为无限循环?为什么?我正在使用Ubuntu 13.04,x86_64。
谢谢。
发生这种情况的原因是int
,架构上的最大值无法达到10000000000。在达到该值之前,它会在某个时间点溢出。因此,条件i < 10000000000
将始终评估为true,这意味着这是一个无限循环。
编译器能够在编译时进行推断,这就是为什么它为无限循环生成适当的汇编的原因。
编译器可以就此警告您。为此,您可以使用以下命令启用“额外”警告级别:
gcc -Wextra
例如,GCC 4.8.2会告诉您:
warning: comparison is always true due to limited range of data type [-Wtype-limits]
for (i = 0; i < 10000000000; ++i);
^
而且,它甚至还告诉您特定的警告选项,它可以精确控制这种警告类型(Wtype-limits)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句