与运营商的整数促销<<

时间:2012-06-26 07:58:10

标签: c integer-promotion

与问题Bitshift and integer promotion?类似,我在使用左位移时有一个关于整数提升的问题。

unsigned int test(void)
{
  unsigned char value8;
  unsigned int result;

  value8 = 0x12;
  result = value8 << 8;
  return result;
}

在这种情况下,value8首先会提升为unsiged int还是具体实现?

  

6.5.7按位移位运算符 ... 3 Sematics ...
  对每个操作数执行整数提升。结果的类型是   升级的左操作数。如果右操作数的值为负或是   大于或等于提升的左操作数的宽度,行为是未定义的。

它表示“整数促销是在每个操作数上执行的。”,但这里的促销规则是什么?

我认为它应该是convert to int if lesser rank than int,但我找不到它。

我问这个,因为一个编译器(Renesas nc30wa)没有提升为int,所以我的样本的结果总是为0。

在这个平台上,char是8位宽,16位。

2 个答案:

答案 0 :(得分:13)

短语“整数促销”是一个非常具体的内容,可在(对于C99)部分6.3.1.1 Booleans, characters, and integers中找到:

  

如果int可以表示原始类型的所有值,则该值将转换为int;   否则,它将转换为unsigned int。这些被称为整数   促销活动。所有其他类型都不会被整数促销更改。

假设您的unsigned char可以保留在int中,则会将其提升为int。在unsigned charint一样宽的罕见平台上,它会提升为unsigned int

这只在C11中略有改变:

  

如果int可以表示原始类型的所有值(由宽度限制,对于a   bit-field),将值转换为int;否则,它将转换为无符号   INT。这些被称为整数促销。所有其他类型都没有改变   整数促销。

如果特定编译器不遵循此行为,那么它并不真正符合要求。但是,鉴于您列出的编译器适用于嵌入式系统,因此并不奇怪。

许多是为特定目的而构建的,并且要求列表中的一致性并不总是很高。可能存在编译器标志,使其更符合标准。


查看您的特定环境,M16C Series,R8C Family C Compiler Package V.5.45 C Compiler(请参阅here)在2.1.4 nc30 Command Line Options部分中有f. Generated code modification options小节:

  

-fextend_to_int(-fETI):
  将char类型数据扩展为int类型后执行操作。根据ANSI标准进行扩展。

虽然我怀疑-fansi可能是更好的选择,因为它也涵盖了其他一些事情。

答案 1 :(得分:3)

value8被提升为int,假设转化排名unsigned char低于转化排名int(通常在大多数平台上都是如此)。

整数的转换等级在6.3.1.1中的C99中描述。

请注意,默认情况下,某些编译器会禁用整数提升规则。例如,MicroChip编译器MPLAB C18。在编译器的文档中查找ISO一致性。