C++ 将无符号字符按位左移16是什么意思
我正在读取一个包含C++ 将无符号字符按位左移16是什么意思,c++,c,bit-manipulation,C++,C,Bit Manipulation,我正在读取一个包含无符号字符变量的.cpp文件,它正在尝试按位左移16位,因为无符号字符由8位组成,左移16位将擦除所有位并用8个0填充 无符号字符字节=0xff;字节如果char适合int,它将被提升为int,结果将与您期望的一样。如果不是这样,根据标准,它是未定义的行为,并且可能会发出编译警告。根据标准: 对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负数或大于或等于提升后的左操作数的宽度,则行为未定义。当您移动值时 unsigned char x = ...
无符号字符
变量的.cpp文件,它正在尝试按位左移16位,因为无符号字符
由8位组成,左移16位将擦除所有位并用8个0填充
无符号字符字节=0xff;字节如果char
适合int
,它将被提升为int
,结果将与您期望的一样。如果不是这样,根据标准,它是未定义的行为,并且可能会发出编译警告。根据标准:
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负数或大于或等于提升后的左操作数的宽度,则行为未定义。
当您移动值时
unsigned char x = ...;
int y = x << 16;
来源:来自n1516(C99草稿):
§6.5.7第3段:位移位运算符
对每个操作数执行整数提升。结果的类型是
提升后的左操作数的值
§6.3.1.1第2段:布尔值、字符和整数
如果int可以表示原始类型的所有值(受宽度限制,例如
位字段),将值转换为整数;否则,它将转换为未签名的
整数。这些被称为整数促销
脚注:
1:一些DSP芯片以及某些克雷超级计算机已知具有sizeof(char)==sizeof(int)
。这以额外的内存消耗为代价简化了处理器负载存储单元的设计
2:如果你的左移位被提升到int
,然后溢出int
,这是未定义的行为(恶魔可能会从你鼻子里飞出来)。相比之下,溢出一个无符号
总是定义良好的,因此位移位通常应该在无符号
类型上进行。表达式的值没有赋值。如前所述,编译器将优化移位操作,而不执行任何操作。真正的代码是什么?您可能想看看这个:所有内置操作符都处理至少为int大小的对象(请参阅)。因此:sizeof(字节如果char
不能放入int
,它将永远不会导致未定义的行为,因为它必须装入无符号int
,并且无符号int
上的移位永远不会被定义。只有有符号整数上的移位才是未定义的,并且只有当数学结果不能用类型表示时。例如le,1整数提升确实被执行,这意味着只有当无符号字符
被提升为int
而不是无符号int
时,行为才是未定义的,并且移位将产生一个无法在int
@DietrichEpp中表示的值:甚至0非常感谢您的精心设计解释。虽然我仍然对将unsigned char
升级为int
@leomayleomay后可能意外覆盖的内存感到困惑。但它不是这样工作的。如果将int
赋值给unsigned char
变量,则会转换int
。(这毕竟不是汇编语言。)所以这里的按位左移(16向左)将使所讨论的变量为0,对吗?如果赋值x=x,我发现这种行为非常令人惊讶。我使用IAR CSTAT静态分析工具为以下代码遇到了这种行为:无符号短BE2LE16(无符号短x){return((x8));}直到你详细的回答才明白。非常感谢你和我!
/* All three are exactly equivalent */
x << 16;
x << 16u;
x << (unsigned char) 16;