Why result of unsigned char << unsigned char is not unsigned char

我怕爱的太早我们不能终老 提交于 2019-12-05 05:45:21

Quoting some draft of the 2011 standard:

5.8 Shift operators [expr.shift]

...

The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand.

and

4.5 Integral Promotions [conv.prom]

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int

...

So, value is promoted to int, and the type of value << shift is the type of the promoted left operand, i.e. int.

You can achieve your desired result one of these ways:

std::cout << "result " << ((unsigned char)(value << shift)) << "\n";
std::cout << "result " << ((value << shift)&0xff) << "\n";

Just cast it back to an unsigned char:

std::cout << "result " << static_cast<unsigned char>(value << shift) << "\n";

Or, use bitwise-AND:

std::cout << "result " << ((value << shift) & 0xFF) << "\n";

You could mask the bits you're interested in:

(value << shift) & 0xff

What you are seeing is a result of integer promotion, and is a part of the language. Imagine you're composing a 16-bit integer from 2 8-bit ones - you wouldn't want to manually promote to a higher width integer to get the high and low bits into the right place, right?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!