20

我有以下函数用于读取大端四字(在抽象基文件 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() 函数读取一个 BYTE。以下是使用的 typedef:

typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef unsigned long   DWORD;

问题是我在移位操作的前四行收到了 4 个编译器警告:

警告 C4293:“<<”:移位计数为负数或太大,未定义的行为

我理解为什么会出现此警告,但我似乎无法弄清楚如何正确摆脱它。我可以做类似的事情:

qT |= (unsigned long long)readb() << 56;

这消除了警告,但没有任何其他问题,BYTE 会一直正确延长吗?也许我只是想太多了,解决方案就是这么简单。你们能帮我吗?谢谢。

4

2 回答 2

16

您删除警告的方式是正确的。正如您可能已经知道的那样,出现警告是因为您试图将字节的内容移动到单词的边界之外,然后将其存储在四字中。此操作未定义。(它会在赋值之前评估赋值的右侧。)通过首先显式转换,现在有足够的空间来进行移位,所以没有什么可抱怨的。

可以说,编译器应该能够确定您要将它存储在四字中,因此它应该首先分配一个四字并在那里进行移位,但它可能还不够聪明,无法弄清楚。

另外,我不确定这一点,但可能为 x64 编译它也不会产生警告,因为一个字是 64 位?

于 2010-06-11T07:29:57.027 回答
2

qT |= (unsigned long long)readb() << (shiftvalue & 63); 假设您不需要超过 63 位移位,这将是完美的解决方案

于 2015-07-08T03:51:30.403 回答