班次计数为负或错误太大 - 正确的解决方案?
我有以下函数用于读取大端四字(在抽象基本文件 I/O 类中):
unsigned long long File::readBigEndQuadWord(){
unsigned long long qT = 0;
qT |= readb() << 56;
qT |= readb() << 48;
qT |= readb() << 40;
qT |= readb() << 32;
qT |= readb() << 24;
qT |= readb() << 16;
qT |= readb() << 8;
qT |= readb() << 0;
return qT;
}
readb() 函数读取一个字节。以下是使用的 typedef:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
问题是,我在使用移位操作的前四行收到 4 个编译器警告:
警告 C4293:“<<” : 班次计数 负数或太大,未定义 行为
为什么会出现此警告,但我似乎无法弄清楚如何正确摆脱它。我可以这样做:
qT |= (unsigned long long)readb() << 56
;
这消除了警告,但是没有其他问题吗,BYTE 会一直正确扩展吗?也许是我想太多了,解决办法就是这么简单。你们能帮我一下吗?谢谢。
I have the following function for reading a big-endian quadword (in a abstract base file I/O class):
unsigned long long File::readBigEndQuadWord(){
unsigned long long qT = 0;
qT |= readb() << 56;
qT |= readb() << 48;
qT |= readb() << 40;
qT |= readb() << 32;
qT |= readb() << 24;
qT |= readb() << 16;
qT |= readb() << 8;
qT |= readb() << 0;
return qT;
}
The readb() functions reads a BYTE. Here are the typedefs used:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
The thing is that i get 4 compiler warnings on the first four lines with the shift operation:
warning C4293: '<<' : shift count
negative or too big, undefined
behavior
I understand why this warning occurs, but i can't seem to figure out how to get rid of it correctly. I could do something like:
qT |= (unsigned long long)readb() << 56
;
This removes the warning, but isn't there any other problem, will the BYTE be correctly extended all the time? Maybe i'm just thinking about it too much and the solution is that simple. Can you guys help me out here? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您删除警告的方法是正确的。您可能已经知道,出现警告是因为您试图将字节的内容移动到单词的边界之外,然后将其存储在四字中。该操作未定义。 (它会在赋值之前评估赋值的右侧。)通过首先显式转换,现在有足够的空间来进行移位,因此没有什么可抱怨的。
可以说,编译器应该能够确定您要将其存储在四字中,因此它应该首先分配一个四字并在那里进行移位,但它可能不够聪明,无法弄清楚这一点。
另外,我对此也不确定,但可能为 x64 编译它也不会生成警告,因为一个字是 64 位?
Your way of removing the warning is correct. As you probably do already know, the warning is occurring because you're trying to shift the contents of a byte beyond the boundaries of a word, then store it in the quadword. This operation is undefined. (It will evaluate the right-side of the assignment before assigning the value.) By explicitly casting first, there is now enough space to do the shift, so there's nothing to complain about.
Arguably, the compiler should be able to figure out you're going to store it in the quadword, so it should allocate a quadword first and do the shift there, but it might not have been made smart enough to figure it out.
Also, I'm not sure about this, but possibly compiling this for x64 will also not generate the warning, as one word is 64 bits?
qT |= (unsigned long long)readb() << (移位值&63);
假设您不需要超过 63 位移位,这将是完美的解决方案
qT |= (unsigned long long)readb() << (shiftvalue & 63);
This will be perfect solution assuming u dont requiered more than 63 bit shift