为什么unsigned char << unsigned char的结果不是unsigned char

use*_*809 7 c++ bit-manipulation

我从左移获得结果,我无法找到解释.

unsigned char value = 0xff; // 1111 1111
unsigned char  = 0x01; // 0000 0001

std::cout << "SIZEOF value " << sizeof(value) << "\n"; // prints 1 as expected
std::cout << "SIZEOF shift " << sizeof(shift) << "\n"; // prints 1 as expected

std::cout << "result " << (value << shift) << "\n"; // prints 510 ???

std::cout << "SIZEOF result " <<  sizeof(value << shift) << "\n"; // prints 4 ???
Run Code Online (Sandbox Code Playgroud)

我期待结果,1111 1110但我得到int(?)的价值1 1111 1110.

如何将无符号字符的位移到左侧,以便截断位,结果为1111 1110?

我要做的是读取一系列字节并将它们解释为不同长度(1-32位)的整数.

F0        F5
1111 0000 1111 0101 
Run Code Online (Sandbox Code Playgroud)

可能

0F (first 4 bits)
0F (next 8 bits)
05 (last 4 bits)
Run Code Online (Sandbox Code Playgroud)

这与使用小于int的类型进行算术这一事实有关吗?

Rob*_*obᵩ 9

引用2011年标准的一些草案:

5.8移位运算符[expr.shift]

...

操作数应为整数或无范围的枚举类型,并执行整体促销.结果的类型是提升的左操作数的类型.

4.5积分促销[conv.prom]

如果int可以表示源类型的所有值,则除了bool,char16_t,char32_t或wchar_t之外的整数类型的prvalue(其整数转换等级(4.13)小于int的等级)可以转换为int类型的prvalue ; 否则,源prvalue可以转换为unsigned int类型的prvalue

...

因此,value被提升为int,并且类型是value << shift被提升的左操作数的类型,即int.

您可以通过以下方式之一获得所需的结果:

std::cout << "result " << ((unsigned char)(value << shift)) << "\n";
std::cout << "result " << ((value << shift)&0xff) << "\n";
Run Code Online (Sandbox Code Playgroud)