班次计数为负数或太大错误 - 正确的解决方案?

时间:2010-06-11 07:22:01

标签: c++ math bit-shift

我有以下函数用于读取big-endian四字(在抽象基本文件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:'&lt;&lt;' :班次计数   负面或太大,未定义   行为

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

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

这会删除警告,但是没有任何其他问题,BYTE是否会一直正确扩展?也许我只是想太多而且解决方案很简单。你能帮助我吗?感谢。

2 个答案:

答案 0 :(得分:15)

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

可以说,编译器应该能够弄清楚你是要将它存储在四字中,所以它应该首先分配一个四字并在那里进行移位,但它可能没有足够聪明地弄清楚它

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

答案 1 :(得分:2)

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