C 中的变量提升

Variable promotion in C

我无法弄清楚为什么在每个特定情况下输出都不同。在示例代码a中,如我​​所料,有一个变量提升,结果是> 6,但在示例代码b中,结果是<= 6:

/* **Code a** */
puts("Code a\n");
unsigned int a = 6;
int b = -20;
( a+b > 6) ? puts("> 6\n") : puts("<= 6\n");

/* **Code b** */
puts("Code b:\n");
uint8_t a1 = 6;
int8_t  b1 = -20;  
( a1+b1 > 6) ? puts("> 6\n") : puts("<= 6\n");

输出:

Code a

> 6

Code b:

<= 6

通常的算术转换是对加法的操作数进行的。对于整数类型,这包括整数提升(如果需要),并且如果两个操作数的类型不同,则进行进一步的转换以使它们成为通用类型。

在第一种情况下没有提升,但是 int 操作数被转换为 unsigned int 因为 int 不能容纳 unsigned int 的所有可能值。

在第二种情况下,两个操作数都被提升为 int 并保持为 int,因为它们具有共同的类型。

参考 C11 标准草案 6.5.6 加法运算符 说:

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

部分 6.3.1.8 通常的算术转换说:

Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions

[...]

Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands

[...]

  • Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type

[...]

可以在问题中找到对此的基本原理的一个很好的参考:Why must a short be converted to an int before arithmetic operations in C and C++?