C++ 为什么整数溢出未定义行为仅适用于有符号整数,而不适用于无符号整数?

C++ 为什么整数溢出未定义行为仅适用于有符号整数,而不适用于无符号整数?,c++,C++,使有符号整数溢出行为未定义的目的是允许编译器优化。但是,这不是一个同样有效的参数,可以使无符号整数溢出行为不被定义吗?保持无符号整数溢出不被定义的目的可能是编译器优化1。但最初的原因是标准没有定义有符号整数的位表示。不同的实现提供了不同的有符号整数表示,它们的溢出特性也会不同。这是允许的,因为标准没有定义这些溢出特性是什么 相比之下,无符号整数位表示总是定义良好的(否则,无法有效地执行许多按位操作),因此它们的溢出行为也可以定义良好 对于特定大小的无符号整数,在该值表示形式下,布尔运算以最大无符

使有符号整数溢出行为未定义的目的是允许编译器优化。但是,这不是一个同样有效的参数,可以使无符号整数溢出行为不被定义吗?

保持无符号整数溢出不被定义的目的可能是编译器优化1。但最初的原因是标准没有定义有符号整数的位表示。不同的实现提供了不同的有符号整数表示,它们的溢出特性也会不同。这是允许的,因为标准没有定义这些溢出特性是什么

相比之下,无符号整数位表示总是定义良好的(否则,无法有效地执行许多按位操作),因此它们的溢出行为也可以定义良好

对于特定大小的无符号整数,在该值表示形式下,布尔运算以最大无符号值+1为模。因此,标准有一种方式来说明任何数学运算的结果是什么:它是期望的数值结果,模最大无符号值+1

也就是说,如果一个16位无符号整数包含65535,并将其加1,则数值结果为65536。但是,在16位数字中得到的结果是0。这是标准定义它的方式,因为这是布尔算术在特定位深度下的工作方式。表示定义了行为

相反,不同的有符号整数形式具有不同的溢出特性。如果标准在16位有符号整数中定义了32767+1的特定含义,那么如果特定的有符号整数表示不能自然地提供该答案,编译器将不得不更改如何添加这些值以生成该答案。对于有符号/幅值,此相加结果为-0。如果标准规定了实际的行为,那么每两个补码的实现将不能仅仅添加数字。它必须检查溢出并伪造结果

在每一个数学运算中


1还有其他原因,例如大多数代码不允许它定义得那么好。这是大多数代码,如果定义良好,则有符号整数溢出将被破坏。

有符号整数有不同的表示形式,溢出行为也不同。正如我所知道的,只有一个表示用于无符号。注意,在C++术语中,无符号整数永远不会溢出:它们只能环绕,因为标准要求使用无符号整数的模运算。类型“为什么语言设计者做出了这个决定而不是那个决定”的问题。通常无法回答。我不确定我是否明白这一点。实现定义了符号整数表示;编译器是不允许对这些位发生的事情讳莫如深的。那么,为什么溢出行为不会从中产生呢?@Sneftel示例:一些硬件使用(使用)符号幅度;一些使用1s补码,其他硬件可能会在有符号溢出时捕获(故障)etc@RichardCritten是的,我知道。因此我的评论。@Sneftel:表示是实现定义的,它们的含义不是。要定义整数溢出,必须有一条语句,说明当您获取最大有符号整数并向其添加1时得到的数字。定义这一点需要定义一个表示,或者强制所有表示都执行符合特定答案所需的任何操作。