比较表达式中的无符号整数溢出

Unsigned integer overflow in comparison expressions

在 C 语言中,使用以下代码片段:

uint16_t a = 243;
uint16_t b = 65535;
uint16_t max = 65535;

if ((a + b) > max)
{
   printf("Out of range!");
}
else
{
   printf("Within range.");
}

结果将是“超出范围!”。在这种情况下适用什么类型转换规则?谁能告诉我有据可查的来源?

谢谢!

来自 C 标准(6.5.6 加法运算符)

4 If both operands have arithmetic type, the usual arithmetic conversions are performed on them.

和(6.5.8 关系运算符)

3 If both of the operands have arithmetic type, the usual arithmetic conversions are performed.

最后(6.3.1.8 常用算术转换)

  1. ... Otherwise, the integer promotions are performed on both operands.

and (6.3.1.1 Boolean, characters, and integers)

2 The following may be used in an expression wherever an int or unsigned int may be used: — An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int. — A bit-field of type _Bool, int, signed int, or unsigned int. If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions.

所以在if语句的条件下

if ((a + b) > max)

所有操作数根据整数提升转换为int类型。 int 类型的对象能够存储整数表达式 a + b 的值,其中每个操作数依次转换为 int.

类型

其实上面的if语句你可以想象成下面的样子

if ( ( ( int )a + ( int )b ) > ( int )max )

或喜欢

if ( ( ( unsigned int )a + ( unsigned int )b ) > ( unsigned int )max )

取决于类型intunsigned int是否可以存储类型uint16_t的值。

如果类型 intunsigned int 的大小与类型 uint16_t.

的大小相同,则可能会发生溢出

如果int比17位宽,abmax将被转换为inta + b 不会溢出并且会产生大于 max.

的结果

如果int是17位宽,abmax将被转换为inta + b 会溢出,C 标准没有定义该行为。

如果int是16位宽,abmax将不会被转换。 a + b 将换行并产生小于 max.

的结果