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++?。
我无法弄清楚为什么在每个特定情况下输出都不同。在示例代码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++?。