与问题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位。
答案 0 :(得分:13)
短语“整数促销”是一个非常具体的内容,可在(对于C99)部分6.3.1.1 Booleans, characters, and integers
中找到:
如果int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int。这些被称为整数 促销活动。所有其他类型都不会被整数促销更改。
假设您的unsigned char
可以保留在int
中,则会将其提升为int
。在unsigned char
与int
一样宽的罕见平台上,它会提升为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一致性。