15

この Web サイトのいくつかの質問は、符号付きと符号なしの型を混在させる場合の落とし穴を明らかにしており、ほとんどのコンパイラはこの型の警告の生成についてうまく機能しているようです。ただし、符号付き定数を符号なし型に割り当てる場合、GCC は気にしないようです! 次のプログラムを検討してください。

/* foo.c */
#include <stdio.h>
int main(void)
{
    unsigned int x=20, y=-30;
    if (x > y) {
        printf("%d > %d\n", x, y);
    } else {
        printf("%d <= %d\n", x, y);
    }
    return 0;
}

以下のように GCC 4.2.1 でコンパイルすると、コンソールに何も出力されません。

gcc -Werror -Wall -Wextra -pedantic foo.c -o foo

結果の実行可能ファイルは、次の出力を生成します。

$ ./foo
20 <= -30

-30符号付きの値を符号なしの整数変数に割り当てるときに、GCC が警告またはエラー メッセージを生成しない理由はありますyか?

4

3 に答える 3

22

-Wconversionを使用します。

~/src> gcc -Wconversion -Werror -Wall -Wextra -pedantic -o signwarn signwarn.c
cc1: warnings being treated as errors
signwarn.c: In function 'main':
signwarn.c:5: error: negative integer implicitly converted to unsigned type

ここで問題になるのは、gcc は実際には警告を生成するのに非常に優れているということですが、(予期しない場合もある) ケースではデフォルトで警告を生成しないようになっていると思います。利用可能な警告を参照し、役立つと思われる警告を生成する一連のオプションを選択することをお勧めします。またはそれらすべてだけで、そのコードが輝くまで磨いてください! :)

于 2010-05-05T08:24:37.050 に答える
9

負の値を符号なし型に変換できるのは C 言語の機能です。このため、デフォルトでは警告は発行されません。必要に応じて、明示的にリクエストする必要があります。

あなたのプログラムが出力するものについては...型の範囲を超えている符号なしの値で%dフォーマット指定子を使用すると、未定義の動作が発生します。これは、実験で実際に観察したことです。printfint

于 2010-05-05T08:43:10.677 に答える
2

(unsigned)-1 を使用することは、すべてのビットを設定するためによく使用される方法であり、C のこの (誤った) 機能の理由として引用されることさえあります。それは明白でも移植可能でもありません-すべてのビットを設定するために使用したい式は ~0 です。

于 2016-08-17T21:03:51.740 に答える