【发布时间】:2014-01-19 14:18:52
【问题描述】:
我正在运行一些测试以查看 ++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
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>
根据我的理解,这是无限循环,导致生成完全相同的 asm:
for(i=0;;++i);
问题是,真的有可能编译成无限循环吗?为什么? 我使用的是 Ubuntu 13.04,x86_64。
谢谢。
【问题讨论】:
-
您认为
i可以在您的架构中保留10000000000吗? -
对如此大的数字使用
long long int。并查看limits.h以了解整数类型的大小。 -
任何理智的编译器都会为
i++和++i生成完全相同的代码,除非您实际使用结果。 -
如果你用优化编译,所有这样的循环都应该编译成nothing,因为它们显然什么都不做。如果你在没有优化的情况下编译,你的发现可能毫无用处。
-
@hacks 我猜 int 对于这样的数字来说很小,但是这里 cmpl $0xf423f,-0x4(%rbp) 这个数字不在 int 中,它只是一个 const,所以我希望从编译器知道如何处理它