C语言操作数符号不匹配时增强赋值运算符的行为探究
增强赋值运算符(+=)的行为与有符号溢出问题
一、s += u的具体工作机制
对于增强赋值运算符E1 += E2,C标准明确其等价于E1 = E1 + E2(唯一区别是E1只会被求值一次)。针对你给出的代码:
extern signed s; extern unsigned u; s += u;
运算过程遵循以下步骤:
- 触发寻常算术转换:有符号变量
s会被隐式转换为unsigned类型(无符号类型与有符号类型运算时,无符号类型占主导)。 - 执行加法运算:转换后的
(unsigned)s与u相加,结果为unsigned类型(无符号整数的溢出是定义良好的,按模2^N处理,N为类型的位数)。 - 赋值回变量:将加法结果转换为
signed类型,赋值给s。
你给出的等价代码是准确的:
s = (signed)((unsigned)s + u);
二、是否会触发有符号整数溢出的未定义行为?
针对代码:
signed s = INT_MAX; unsigned u = 1; s += u;
不会触发有符号整数溢出的未定义行为,原因如下:
- 加法运算发生在无符号类型域:
s被转换为unsigned后,INT_MAX + 1作为无符号值是合法的(比如32位系统中对应2^31),无符号整数的溢出是定义良好的,不存在未定义行为。 - 最终的赋值是无符号值转有符号值:当无符号值超出有符号类型的表示范围时,这种转换的结果是实现定义的(例如部分编译器会直接按位转换得到
INT_MIN),但这不属于有符号整数运算时的溢出,因此不会触发未定义行为。
内容的提问来源于stack exchange,提问作者CPlus
相关产品推荐
相关产品推荐

