13

我正在读取一个包含unsigned char变量的 .cpp 文件,它正在尝试按位左移 16 位,因为 anunsigned char由 8 位组成,左移 16 位将擦除所有位并用八个 0 填充它。

unsigned char byte=0xff; byte << 16;

4

2 回答 2

18

当你改变一个值时,

unsigned char x = ...;
int y = x << 16;

的类型x被提升为intifunsigned char适合int(大多数系统),或unsignedifunsigned char不适合int(罕见1)。只要您int的宽度为 25 位或更宽,则不会丢弃任何数据2

16请注意,这与具有 type的事实完全无关int

/* All three are exactly equivalent */
x << 16;
x << 16u;
x << (unsigned char) 16;

资料来源:来自 n1516(C99 草案):

§6.5.7 第 3 段:按位移位运算符

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。

§6.3.1.1 第 2 段:布尔值、字符和整数

如果 int 可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为 int;否则,它将转换为无符号整数。这些被称为整数促销。

脚注:

1:已知一些 DSP 芯片以及某些 Cray 超级计算机具有sizeof(char) == sizeof(int)。这以增加内存消耗为代价简化了处理器的加载存储单元的设计。

2:如果你的左移被提升到int然后溢出int,这是未定义的行为(恶魔可能会飞出你的鼻子)。相比之下,溢出 an总是定义明确的,因此通常应该对类型进行unsigned位移。unsigned

于 2012-05-25T04:43:06.373 回答
1

如果char适合 inside int,它将被提升为 an int,结果将如您所愿。如果不是这种情况,则根据标准它是未定义的行为,并且可能会发出编译警告。从标准:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

于 2012-05-25T04:36:09.587 回答