嗨,我是新来的,所以如果有什么问题请告诉我,下次我会努力做得更好。
我试图了解下溢和上溢在 C++ 中的工作原理。我的理解是,如果超出变量的范围,它将从范围的另一端开始。因此,如果 short 的最小值是 -32768 并且我们对其执行 -1 ,则新值应该是 SHRT_MAX 。(32767)这是我的代码:
#include<iostream.h>
#include<limits.h>
#include<conio.h>
int main ( void )
{
int testpositive =INT_MIN ;
short testnegative = SHRT_MIN ;
cout<< SHRT_MIN<<"\n";
cout << testnegative-1<<"\n";
cout << INT_MIN << "\n";
cout << testpositive-1 << "\n";
cout<<testpositive-2;
getch();
return 0;
}
原文由 Knownow 发布,翻译遵循 CC BY-SA 4.0 许可协议
上溢/下溢的确切行为仅针对
unsigned
类型指定。来源: 草案 N3690 §3.9.1 第 4 句
资料来源: N3690 草案第 3.9.1 条注释 47
对于普通的有符号整数类型,C++ 标准只是简单地说,任何事情都可能发生。
资料来源: 草案 N3690 §5 第 4 句
如果我们谈论的是 x86 处理器(或大多数其他现代处理器),那么行为确实正是您所描述的,对于 CPU,有符号值或无符号值之间没有区别(有有符号和无符号 _操作_,但值本身只是位)。
请注意,编译器可以假设(并且大多数现代优化编译器实际上确实假设)在正确的程序中不会发生有符号整数溢出,例如在如下代码中:
编译器可以自由地跳过测试,而生成代码中的
else
分支完全是因为在有效程序中,有符号整数x
总是小于x+1
(因为有符号溢出不能被视为有效行为)。如果将int
替换为unsigned int
但是编译器必须为测试和 else 分支生成代码,因为对于无符号类型,可能会出现x > x+1
。例如 clang 将
foo
的代码编译为您可以在其中看到 ode 只调用了
do_something
两次(除了对rax
的奇怪处理)并且实际上没有提及do_something_else
。或多或少相同的代码由gcc
生成。