3 回答
TA贡献1790条经验 获得超9个赞
历史原因是,大多数C实现(编译器)只使用它使用的整数表示最容易实现的溢出行为。C实现通常使用CPU使用的相同的表示形式,因此溢出行为与CPU使用的整数表示相同。
在实践中,只有符号值的表示才可能因实现而不同:一个是补语,两个是补语,另一个是符号大小。对于无符号类型,标准没有理由允许更改,因为只有一个明显的二进制表示(标准只允许二进制表示)。
相关引文:
C99 6.2.6.1:3:
存储在无符号位字段和类型为无符号字符的对象中的值应使用纯二进制表示法表示。
C99 6.2.6.2:2:
如果符号位为1,则应以下列方式之一修改该值:
-符号位0的相应值被否定(符号和震级);
-符号位的值为−(2)N) (二补);
-符号位的值为−(2)N−1)(补足).
现在,所有处理器都使用两种补码表示,但签名算术溢出仍未定义,编译器制造商希望它保持未定义,因为它们利用这种不确定性来帮助优化。
TA贡献1779条经验 获得超6个赞
TA贡献1863条经验 获得超2个赞
C11 6.5/5
如果在计算表达式过程中出现异常情况(即,如果结果没有数学定义,或者不在其类型的可表示值范围内),则行为是未定义的。
C11 6.2.5/9
有符号整数类型的非负值范围是对应的无符号整数类型的子范围,每个类型中相同值的表示形式是相同的。涉及无符号操作数的计算永远不会溢出,因为不能用结果无符号整数类型表示的结果将被减少,即大于结果类型所能表示的最大值的数字。
C11 6.3.1.3
6.3.1.3有符号整数和无符号整数
当具有整数类型的值转换为_bool以外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。
否则,如果新类型没有符号,则通过重复添加或减去比新类型中可以表示的最大值多一个值来转换值,直到该值位于新类型的范围内为止。
否则,将对新类型进行签名,并且不能在其中表示值;结果要么是实现定义的,要么引发实现定义的信号。
- 3 回答
- 0 关注
- 1249 浏览
添加回答
举报