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行に4つのコンパイラ警告が表示されることです。

警告C4293:'<<':シフトカウントが負または大きすぎる、未定義の動作

この警告が発生する理由は理解できますが、正しく取り除く方法がわからないようです。私は次のようなことをすることができます:

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

これにより警告は削除されますが、他に問題はありません。BYTEは常に正しく拡張されますか?多分私はそれについて考えすぎていて、解決策はとても簡単です。ここで私を助けてくれませんか?ありがとう。

4

2 に答える 2

16

警告を削除する方法は正しいです。おそらくすでにご存知のように、バイトの内容をワードの境界を超えてシフトし、それをクワッドワードに格納しようとしているため、警告が発生しています。この操作は未定義です。(値を割り当てる前に、割り当ての右側を評価します。)最初に明示的にキャストすることにより、シフトを実行するのに十分なスペースがあるため、不満はありません。

おそらく、コンパイラはそれをクアッドワードに格納することを理解できるはずなので、最初にクアッドワードを割り当ててそこでシフトを実行する必要がありますが、それを理解するのに十分なほど賢くされていない可能性があります。

また、これについてはよくわかりませんが、1ワードが64ビットであるため、x64用にこれをコンパイルしても警告は生成されない可能性がありますか?

于 2010-06-11T07:29:57.027 に答える
2

qT | =(unsigned long long)readb()<<(shiftvalue&63); これは、63ビットシフト以上を必要としないことを前提とした完璧なソリューションになります

于 2015-07-08T03:51:30.403 に答える