状況:
32 ビット用にコンパイルすると機能するが、gcc 4.6 で 64 ビット用にコンパイルすると失敗するコードがあります。問題を特定して標準を調べた後、なぜそれが 32 ビットで機能するのかがよくわかりません。誰かが何が起こっているのか説明できることを願っています。
コード (やや単純化され、興味深い部分に切り詰められています):
// tbl: unsigned short *, can be indexed with positive and negative values
// v: unsigned int
// p: unsigned char *
tmp = tbl[(v >> 8) - p[0]]; // Gives segfault when not compiled with -m32
-m32
コードでコンパイルすると動作します。それなしでコンパイルする-m32
と、segfault が発生します。segfault の理由は、64 ビット用にコンパイルさ(v >> 8) - p[0]
れた場合に解釈され、 「否定的な」結果になると解釈されるためです。unsigned int
この質問によると、C99 標準は次のように述べています:
6.2.5c9:A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
このことから、unsigned
マイナスunsigned
は常にunsigned
64 ビットの場合と一致する出力になるようです。これは、私が非常に奇妙だと思う 32 ビットの場合には発生しないようです。
32ビットの場合に何が起こっているのか、誰か説明できますか?