提问人:user16217248 提问时间:5/7/2023 更新时间:5/7/2023 访问量:80
当操作数的符号不匹配时,C 语言中的增强赋值运算符如何表现?
How do the augmented assignment operators in C behave when the signedness of the operands do not match?
问:
我见过一个类似的问题,但我的特指增强赋值运算符,例如 、 等。当我有以下内容时,这些运算符究竟是如何工作的?+=
-=
extern signed s;
extern unsigned u;
s += u;
这等于这个吗?
s = (signed)((unsigned)s+u);
更具体地说,这是否会由于有符号整数溢出而调用未定义的行为?
signed s = INT_MAX;
unsigned u = 1;
s += u;
我知道,当使用普通算术运算符时,无符号类型通常占主导地位。但是,我不确定这是否适用于增强赋值运算符。
答:
这:
s += u;
与此相同:
s = s + u;
根据 C 标准的第 6.5.16.2p3 节:
形式的复合赋值等价于 简单赋值表达式 ,除了左值只计算一次,并且相对于 不确定序列函数调用,化合物的操作 作业是单一评估
E1 op = E2
E1 = E1 op (E2)
E1
所以首先要评估。这会导致按照通常的算术转换转换为类型,并且结果是无符号的。然后将此结果分配回,然后进行从 到 的转换。s + u
s
unsigned
s
unsigned
signed
因此,在这种特殊情况下:
signed s = INT_MAX;
unsigned u = 1;
s += u;
将值 转换为 ,并将 1 相加,从而产生无符号值 。然后,此值将转换为 ,由于该值超出第 6.3.1.3p3 节所述的范围,因此该值将进行实现定义的转换:s
unsigned
INT_MAX + 1
signed
1 当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用 类型,则保持不变。
2 否则,如果新类型为无符号,则通过重复加减比最大值多 1 来转换该值 可以用新类型表示,直到值在 新类型。
3 否则,新类型将被签名,并且不能在其中表示值;结果是实现定义的,或者是 发出实现定义的信号。
所以上面没有未定义的行为,但它确实有实现定义的行为。
上一个:Java 中的位图/位板
下一个:打印无符号长整数时出现问题
评论
x <op>= y
被定义为等同于,但仅评估一次。类型处理与扩展窗体相同。x = x <op> y;
x