为什么内置类型的对象溢出会导致异常/未定义的行为?

时间:2017-07-04 00:29:19

标签: c++ exception overflow narrowing

据我所知,"溢出"非常像"缩小" (如果不是完全相同的话)。

例如,一个值为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';
}

1 个答案:

答案 0 :(得分:1)

没有直觉可以在这里找到,只有规范。 https://stackoverflow.com/a/83763/451600。该规范可能有其决策的历史原因。

例如,++ unsigned_max定义良好且++ signed_max不定,这可能与以下事实有关:并非所有签名数字都以相同的方式表示。 2的补充不是强制性的。

编译器是c ++程序员/程序的黑盒子,只要它遵循规范。