繁体   English   中英

移位计数大于类型的宽度

[英]shift count greater than width of type

我有一个函数,它需要一个int data_length并执行以下操作:

unsigned char *message = (unsigned char*)malloc(65535 * sizeof(char));
message[2] = (unsigned char)((data_length >> 56) & 255);

我得到以下内容:

warning: right shift count >= width of type [-Wshift-count-overflow]
   message[2] = (unsigned char)((data_length >> 56) & 255);

该程序可以按预期工作,但是如何删除编译器警告(不禁用它)? 类似的问题似乎没有使用变量作为要插入的数据,因此似乎解决方案是将其强制转换为int或此类。

标准不允许移位大于所讨论类型的位宽的量,并且这样做会引起未定义的行为

C标准的 6.5.7p3节中有关于位移位运算符的详细信息。

对每个操作数执行整数提升。 结果的类型是提升后的左操作数的类型。 如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为是不确定的。

如果该程序似乎正在运行,则很幸运。 您可以对程序进行不相关的更改,也可以仅在其他计算机上构建它,然后突然一切都停止了。

如果data_length的大小为32位或更小,则右移56位太大。 您只能平移0-31。

问题很简单。 当使用data_length进行无符号化(因为负长度几乎没有意义)时,您将其用作int 为了能够移位56位,该值必须至少为56 57位宽。 否则,行为是不确定的。

在实践中,已知处理器会做很多不同的事情。 在一个例子中,将32位值右移32位将清除变量。 在另一个值中,该值移位了0位( 32 % 32 !)。 然后,在某些情况下,也许处理器认为它是无效的操作码,而OS终止了该进程。

简单的解决方案:声明uint64_t data_length


如果你真的有自己限制在32位数据类型,那么你可以指定0到这些字节即表示最显著字节。 或者只是在转换前unsigned long longuint64_t转换为uint64_tunsigned long long

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM