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

C++ 为什么内置类型的对象上的溢出会导致异常/未定义行为?,c++,exception,overflow,narrowing,C++,Exception,Overflow,Narrowing,据我所知,“溢出”与“缩小”非常相似(如果不是完全相同的话) 例如,值为255的无符号字符对象;它的位模式都是1:1111111 因此,通过向对象添加1:char_object++ 加宽将发生在某个临时对象上,向其添加1,因此位模式(在临时对象上)应为256:0000 0001 0000 然后将临时副本分配到原始对象中,导致缩小(丢失最左边的字节),从而使其值为0 如果这和缩小一样有效,我很好奇为什么标准建议在某些机器上,溢出会导致异常?一些书甚至建议作为结果的未定义的行为。这难道不意味着缩小在

据我所知,“溢出”与“缩小”非常相似(如果不是完全相同的话)

例如,值为255的无符号字符对象;它的位模式都是1:1111111

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


加宽将发生在某个临时对象上,向其添加1,因此位模式(在临时对象上)应为256:0000 0001 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';
}
#包括
#包括
#包括
无效显示位(int8&);
int main()
{
for(整数{1};数;++数)
{
显示_位(数字);
}
返回0;
}
无效显示位(整数和数字)
{

std::cout这里没有直觉,只有规范。规范可能有其决策的历史原因

例如,++unsigned_max定义得很好,++signed_max没有定义,这可能与并非所有有符号数字都以相同的方式表示有关。2的补码不是强制要求的


<编译器>是C++程序员/程序的黑盒,只要它遵循SPEC.< /P>转换不溢出。<代码> C=100000;< /C> >可能是实现定义的值。溢出是算术表达式中发生的事情,例如:代码> int n=int最大;+/n;< /C> >溢出。只有符号整数溢出。(因此,如果
sizeof(unsigned int)==1
,则unsigned char将升级为unsigned int,并且
char\u object++
不会溢出。)“加宽将在某个临时对象上发生,并向其添加1,因此位模式(在临时对象上)应为256:0000 0001 0000然后将临时副本分配到原始对象中,导致缩小(丢失最左边的字节),从而使其值为0。”这在概念层面上可能是正确的。@ CastIjrIrFaE,这就是为什么我必须问这个潜在的空洞的问题。我对计算机体系结构了解不多,或者对C++代码在引擎盖下的工作方式了解得不够。我想很多程序员不会真的关心这类事情,但在这方面我很奇怪。可能是@KerrekSB的重复,我有点明白你的意思。一个带最大值的带符号int类型可能会有位模式1111111111111111111111111111111111111111。加上一个会变成1000万0 0000.