2

据我所知,“溢出”的工作原理非常类似于“缩小”(如果不是完全一样的话)。

例如,一个值为 255 的 unsigned char 对象;它的位模式将全为 1:1111 1111

因此,通过向对象加 1:char_object++;

在一些临时对象上会发生加宽,添加了 1,因此位模式(在临时对象上)应该是 256: 0000 0001 0000 0000

然后将临时对象复制分配到原始对象中,导致变窄(丢失最左边的字节),使其值为 0。

如果这像缩小一样起作用,我很好奇为什么标准建议在某些机器上,溢出会导致异常?有些书甚至建议未定义的行为作为结果。这难道不意味着缩小会在所述机器上做同样的事情吗?如果它们不是同一个东西,那么它们有什么不同呢?

(编辑:)也许通过将无符号 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';
}
4

1 回答 1

1

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

例如,++unsigned_max 定义明确而 ++signed_max 定义不明确这一事实可能与并非所有有符号数都以相同方式表示的事实有关。2 的补码不是强制性的。

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

于 2017-07-04T00:57:39.527 回答