我想知道在这种情况下C ++的行为如何:
char variable = 127;
variable++;
在这种情况下,变量现在等于-128。但是,增量运算符是将值包装到其下限还是发生了溢出?
发生溢出并导致未定义的行为。
第5.5节:
如果在评估表达式时,结果不是数学定义的,或者在其类型的可表示值范围内,则行为未定义[...]
该标准继续指出,在大多数实现中,整数溢出被忽略。但这并不代表保证。
普通char
可以是签名或未签名。如果最大值为127,则必须在您的实现中签名。
对于无符号类型,“溢出”定义良好,并导致环绕。对于有符号类型,算术溢出的行为是未定义的(环绕是典型的,但不是必需的)。但这实际上并不适用于这种特殊情况;相反,存储在variable
中的值是实现定义的。
对于比int
更窄的类型,事情有点复杂。这个:
variable ++;
相当于:
variable = variable + 1;
+
运算符的操作数应用了“通常的算术转换”,在这种情况下意味着两个操作数都被提升为int
。因为int
的宽度足以保持结果,所以没有溢出;结果是128
,并且是int
类型。当该结果存储回variable
时,它将从int
转换为char
。
对于转换,溢出的规则与对“+”等算术运算的规则不同。对于签名到签名或无符号到签名的转换,如果该值无法在目标类型中表示,则行为不是未定义的;它只是产生一个实现定义的结果。
对于使用带符号整数类型的二进制补码表示的典型实现,存储的值可能是-128 - 但其他行为也是可能的。 (例如,实现可以使用饱和算法。)
另一个(相当模糊)的可能性是char
和int
可能是相同的大小(只有当char
至少为16位时才会发生)。这可能有一些有趣的效果,但我不会进入(尚)。