C中的可变促销

时间:2015-10-02 14:42:16

标签: c integer-promotion

我在解决为什么输出在每种特定情况下都不同时遇到了问题。在示例代码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

1 个答案:

答案 0 :(得分:9)

通常的算术转换是在加法操作数上执行的。对于整数类型,如果需要,这包括整数提升,如果两个操作数不具有相同类型,则进行进一步转换以将它们带到公共类型。

在第一种情况下,没有促销活动,但int操作数已转换为unsigned int,因为int无法保存unsigned int的所有可能值。

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

作为参考,6.5.6 添加剂运算符部分中的C11标准草案说:

  

如果两个操作数都具有算术类型,则执行通常的算术转换   它们。

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

  

许多期望算术类操作数的运算符会导致   以类似的方式转换和生成结果类型。 目的是为了   确定操作数和结果的通用实数类型。为了   指定的操作数,每个操作数都被转换,不改变类型   域,对应的实际类型是普通实数的类型   类型。 除非另有明确说明,否则常见的实际类型也是如此   结果的相应实际类型,其类型域为   操作数的类型域,如果它们是相同的,并且是复杂的   除此以外。这种模式称为通常的算术转换

     

[...]

     

否则,将对两个操作数执行整数提升。那么   以下规则适用于提升的操作数

     

[...]

     
      
  • 否则,如果具有无符号整数类型的操作数的等级大于或等于   等于另一个操作数的类型的等级,然后是操作数   有符号整数类型转换为带有unsigned的操作数的类型   整数类型
  •   
     

[...]

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