以下代码进入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;
}
Run Code Online (Sandbox Code Playgroud)
所以这是交易:有符号整数溢出在技术上是未定义的行为.但是x86上的GCC使用x86整数指令实现整数运算 - 它包含溢出.
因此,我本来期望它包装溢出 - 尽管事实上它是未定义的行为.但事实显然并非如此.那么我错过了什么?
我使用以下方法编译:
~/Desktop$ g++ main.cpp -O2
Run Code Online (Sandbox Code Playgroud)
GCC输出:
~/Desktop$ ./a.out
536870912
1073741824
-2147483648
0
0
0
... (infinite loop)
Run Code Online (Sandbox Code Playgroud)
禁用优化后,没有无限循环且输出正确.Visual Studio也正确编译它并给出以下结果:
正确的输出:
~/Desktop$ g++ main.cpp
~/Desktop$ ./a.out
536870912
1073741824
-2147483648
3
Run Code Online (Sandbox Code Playgroud)
以下是一些其他变体:
i *= 2; // Also …Run Code Online (Sandbox Code Playgroud) 我在C规范中读到一点,无符号变量(特别是unsigned short int)执行一些所谓的整数溢出回绕,虽然我找不到任何有符号变量,除了我留下未定义的行为.我的教授告诉我他们的价值观也被包围了.(也许他只是意味着gcc)我认为这些位被截断了,我留下的位给了我一些奇怪的价值?!那么,任何人都可以解释什么是环绕的,它与仅截断位有什么不同.
我希望签名整数在它们变得太大时溢出.如何在不使用下一个最大数据类型的情况下(或者当我已经在int128_t时)实现这一目标?
例如,使用8位整数19*12通常是260,但我希望结果1 11 10 01 00第9位被截止,因此-27.