符号付き値が符号なし整数に代入されるときにコンパイラがエラーを返さないのはなぜですか?- C++
-
12-09-2019 - |
質問
知っている 符号なし整数 負の値を保持することはできません。ただし、次のコードはエラー/警告なしでコンパイルされます。
unsigned int a = -10;
変数を出力するとき ある, 、間違った値が出力されます。符号なし変数が符号付き値を保持できない場合、コンパイラはなぜエラーや警告を表示せずに変数をコンパイルできるのでしょうか?
何かご意見は?
編集
コンパイラ:VC++コンパイラ
解決
警告レベル4を使用する必要があります。
解決
Microsoft Visual C++:
警告 C4245:'初期化中' :「int」から「unsigned int」への変換、署名/符号なしのミスマッチ
警戒レベル4です。
G++
次のような警告が表示されます。
警告:負の値の変換
-0x00000000a' to
符号なし整数
-W ディレクティブなし。
GCC
以下を使用する必要があります:
gcc main.c -Wconversion
これにより、次の警告が表示されます。
警告:負の整数は暗黙的に符号なし型に変換されます
-Wall ではこの警告は有効にならないことに注意してください。
おそらく、警告レベルを上げる必要があるかもしれません。
他のヒント
を変換する signed int
に unsigned int
これは C 標準では「通常の算術変換」として知られているものなので、エラーではありません。
コンパイラがデフォルトでこれに関して警告を発行しないことが多い理由は、これがコード内で非常に一般的に行われるため、一般に発行される「誤検知」警告が多すぎるためです。で動作するコードが非常にたくさんあります signed int
本質的に署名されていないものを処理するための値 (バッファ サイズの計算など)。また、式の中で符号付きの値と符号なしの値を混在させることもよくあります。
これらのサイレント変換がバグの原因ではないというわけではありません。したがって、最初から「クリーン」な状態にするために、新しいコードに対する警告を有効にすることは悪い考えではないかもしれません。ただし、既存のコードによって発行される警告に対処するのはおそらくかなり大変だと思われると思います。
-10 は整数値として解析され、int を unsigned int に代入することが許可されます。何か間違ったことをしていることを知るために、コンパイラは整数 (-10) が負であるか正であるかをチェックする必要があります。単なる型チェックではないので、パフォーマンスの問題から無効になっているのだと思います。
gcc コンパイラの場合は追加できます
gcc -Wconversion ...
これにより、次の警告が生成されます
warning: converting negative value '-0x0000000000000000a' to 'unsigned int'
私は g++ 4.9.2 を使用していますが、この警告を表示するには -Wsign-conversion を使用する必要があります。
gcc.gnu.org:C++ では、-Wsign-conversion が明示的に有効になっていない限り、符号付き整数と符号なし整数の間の変換に関する警告はデフォルトで無効になります。