据我所知,"溢出"非常像"缩小" (如果不是完全相同的话)。
例如,一个值为255的unsigned char对象;它的位模式将全部为1:1111 1111
因此,通过向对象添加1:char_object ++;
某些临时对象会发生加宽,添加1,所以位模式(临时)应为256:0000 0001 0000 0000
然后将临时文件复制分配到原始对象中,从而导致缩小(丢失最左边的字节),从而使其值为0.
如果这可以缩小范围,我很好奇为什么标准表明在某些机器上溢出会导致异常?有些书甚至建议将未定义的行为作为结果。这是否意味着缩小会在所述机器上做同样的事情?如果它们不是同一个东西,那么它们有何不同?
(edit :)也许通过比较无符号8位对象的位模式与带符号的8位对象的位模式,可以使其更清晰?似乎在2的补码中,位模式不会改变,但表示确实如此。无论如何,这仍然没有真正回答这个问题,"缩小和溢出之间的区别是什么?"因为它们似乎仍然是一样的:
#include <bitset>
#include <cstdint>
#include <iostream>
void show_bits(int8_t&);
int main()
{
for (int8_t number{ 1 }; number; ++number)
{
show_bits(number);
}
return 0;
}
void show_bits(int8_t& number)
{
std::cout << static_cast<int16_t>(number) << ' ';
std::cout << '(' << static_cast<uint16_t>(static_cast<uint8_t>(number)) << ')' << '\t';
std::bitset<sizeof(int8_t) * 8> bits_of(number);
std::cout << bits_of << '\n';
}
答案 0 :(得分:1)
没有直觉可以在这里找到,只有规范。 https://stackoverflow.com/a/83763/451600。该规范可能有其决策的历史原因。
例如,++ unsigned_max定义良好且++ signed_max不定,这可能与以下事实有关:并非所有签名数字都以相同的方式表示。 2的补充不是强制性的。
编译器是c ++程序员/程序的黑盒子,只要它遵循规范。