以下代码:
unsigned char result; result = (result << 4 );
用gcc版本4.6.4(Debian 4.6.4-2)编译,用-Wconversion标志导致警告
警告:从'int'转换为'unsigned char'可能会改变它的值[-Wconversion]
这是为什么?
因为标准是这样说的。 对二元运算符的操作数经历整体提升,其中小于int
任何值都被提升为int
; 该操作的结果也具有int
类型。 如果原始值是0x12
,结果将是0x120
,并将其分配给一个unsigned char
将导致值的变化。 (分配的值将是0x20
。)从哪里警告。
编辑:
从标准(§5.8Shift操作符):“操作数应该是整型或无限型枚举类型,并且执行整型升级,结果的类型是所提升的左操作数的类型。 与其他二元运算符不同, 不需要从两个运算符中找到一个通用类型:结果类型是左操作数的句号。 但整体提升仍然会发生: unsigned char
将被提升为int
(如果int
的大小为1,则为unsigned int
)。
因为int
值可以大于unsigned char
。
想想result
是255
时会发生什么(即0xff
)。 将其左移4位将使其成为4080
(或0xff0
)。 编译器将如何将这个价值转化为result
? 它不能,所以它只是将其截断为240
( 0xf0
)。 换句话说, 整数运算result << 4
的值可以被改变。
所有算术和逻辑运算符对它们的参数执行“积分促销”。 积分提升将小于int
(如unsigned char
)的类型转换为int
或unsigned int
。 如果用<<
替换<<
,你会看到相同的结果。
哦,括号是不需要的。