《Programming principles and practice 2nd》中signed char溢出相关疑问
问题解答
针对问题中的两个示例,性质完全不同,需要分开讨论:
- 第一个示例
int x = 2.9;不属于未定义行为,是C++标准明确规定的隐式浮点-整型转换规则:浮点数向整数转换时会直接截断小数部分,向零取整,所以2.9转int得到2是100%确定的行为,书中的解释完全正确。 - 第二个示例
char c = 1066;要分场景判断:- 首先C++标准中
char的符号是实现定义的,部分平台char默认是unsigned char,这种情况下整数溢出不属于未定义行为,标准明确规定无符号整数溢出会执行模2^N运算(N为对应类型的比特位数量)。常见平台char占8位,1066模256的计算结果恰好是42,结果完全确定。 - 如果平台默认
char是signed char,那么将1066赋值给8位signed char确实属于有符号整数溢出,是标准定义的未定义行为。但斯特劳斯特鲁普在入门教材中的表述特意加了「若使用常见的ASCII字符集」的前提,本质是默认基于主流编译器、主流硬件的通用实现场景:目前几乎所有主流编译器对有符号整数溢出的默认处理都是做低位二进制截断,结果和无符号模运算的结果一致,他是基于这个普遍存在的实现给入门学习者举直观例子,没有在入门阶段引入过于细碎的标准边界细节避免混淆。
- 首先C++标准中
实际开发建议
- 入门学习阶段可以暂时遵循教材的表述理解隐式类型转换的基本逻辑,不用过早纠结极端边角的标准问题
- 生产环境代码绝对不要依赖任何未定义行为或者实现定义行为,如果需要做范围不确定的类型转换,一定要先做范围判断,或者显式使用
static_cast明确表达转换意图,避免出现不可预期的问题。
内容的提问来源于stack exchange,提问作者Itachi Uchiwa
相关产品推荐
相关产品推荐

