ビッグエンディアンのクワッドワードを読み取るための次の関数があります (抽象基本ファイル 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 は常に正しく拡張されるのでしょうか。おそらく私は考えすぎで、解決策はそれほど単純なのでしょう。皆さん、ここで私を助けてくれませんか。ありがとうございます。
ベストアンサー1
警告を削除する方法は正しいです。おそらくすでにご存知のとおり、警告はバイトの内容をワードの境界を超えてシフトしようとしているために発生します。それからそれをクワッドワードに格納します。この操作は未定義です。(値を割り当てる前に、割り当ての右側を評価します。) 最初に明示的にキャストすることで、シフトを行うのに十分なスペースが確保されるため、何も文句を言うことはありません。
おそらく、コンパイラはクワッドワードに格納することを理解できるはずなので、最初にクワッドワードを割り当ててそこでシフトを行うはずですが、それを理解できるほど賢く作られていない可能性があります。
また、これについてはよくわかりませんが、1 つの単語が 64 ビットであるため、これを x64 用にコンパイルしても警告は生成されない可能性があります。