首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么x86上的整数溢出会导致无限循环?

为什么x86上的整数溢出会导致无限循环?
EN

Stack Overflow用户
提问于 2011-10-07 10:24:43
回答 6查看 15.1K关注 0票数 133

在GCC身上,下面的代码进入一个无限循环:

#include <iostream>
using namespace std;

int main(){
    int i = 0x10000000;

    int c = 0;
    do{
        c++;
        i += i;
        cout << i << endl;
    }while (i > 0);

    cout << c << endl;
    return 0;
}

这就是问题所在:整数溢出在技术上是未定义的行为。但是x86上的GCC使用x86整数指令来实现整数运算--这些指令在溢出时被包装起来。

因此,尽管它是未定义的行为,但我希望它在溢出时进行包装。但事实显然并非如此。那么我错过了什么?

我是用编译的:

~/Desktop$ g++ main.cpp -O2

GCC输出:

~/Desktop$ ./a.out
536870912
1073741824
-2147483648
0
0
0

... (infinite loop)

在禁用优化的情况下,没有无限循环,并且输出是正确的。Visual Studio也会正确地编译它,并给出以下结果:

正确输出:

~/Desktop$ g++ main.cpp
~/Desktop$ ./a.out
536870912
1073741824
-2147483648
3

还有一些其他的变体:

i *= 2;   //  Also fails and goes into infinite loop.
i <<= 1;  //  This seems okay. It does not enter infinite loop.

以下是所有相关的版本信息:

~/Desktop$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ..

...

Thread model: posix
gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) 
~/Desktop$ 

所以问题是:,这是“GCC”中的一个bug吗?,?还是我误解了GCC是如何处理整数运算的?

*我也标记了这个C,因为我假设这个bug会在C中重现。(我还没有验证它。)

编辑:

这是这个循环的汇编:(如果我正确识别它的话)

.L5:
addl    %ebp, %ebp
movl    $_ZSt4cout, %edi
movl    %ebp, %esi
.cfi_offset 3, -40
call    _ZNSolsEi
movq    %rax, %rbx
movq    (%rax), %rax
movq    -24(%rax), %rax
movq    240(%rbx,%rax), %r13
testq   %r13, %r13
je  .L10
cmpb    $0, 56(%r13)
je  .L3
movzbl  67(%r13), %eax
.L4:
movsbl  %al, %esi
movq    %rbx, %rdi
addl    $1, %r12d
call    _ZNSo3putEc
movq    %rax, %rdi
call    _ZNSo5flushEv
cmpl    $3, %r12d
jne .L5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7682477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档