8

-Wall-pedanticを使用する

#include <limits.h>
#include <stdio.h>

int main(void)
{
    enum x {
        a,
        max = INT_MAX,
        out_1
    };
    enum y {
        b,
        out_2 = INT_MAX + 1
    };


    printf("%d %d\n", out_1, out_2);
    return 0;
}

clangは

demo.c:9:3: warning: overflow in enumeration value
                out_1
                ^

ご覧のとおり、コンパイラはout_2オーバーフローについて警告しません。コンパイル時に、彼の値は不明ですか?

4

2 に答える 2

3

最初の例では、コンパイラ自体がオーバーフローの原因となっている整数を選択しようとしているため、警告が表示されます。生産している可能性がありINT_MINます。この標準では、aの任意の値をsigned int列挙型定数にすることができます(下を参照)。

2番目の式(INT_MAX + 1)は、に割り当てられる前に計算されout_2ます。ここでの式のオーバーフローは、許可された結果を生成していますが、これは未定義の動作です。有効な結果が列挙型に格納されるため、最初のエラーは生成されません。

clang(3.2)もこれについて警告しませんが、これは事実上同じです。

int a = INT_MAX + 1;

この点で、clangは未定義であるため、C標準に従って動作していません。

比較すると、gccからの出力により、違いが完全に明確になります。

In function ‘main’:
9:9: error: overflow in enumeration values
13:25: warning: integer overflow in expression [-Woverflow]

インテル®コンパイラーは列挙型オーバーフローを無視しますが、整数のオーバーフローについて警告します。

enum.c(13): warning #61: integer operation result is out of range
      out_2 = INT_MAX + 1
                      ^


参考までに、C99標準6.7.7.2.2から、「列挙定数の値を定義する式は、;として表現可能な値を持つ整数定数式でなければなりませんint; .3、」列挙リスト内の識別子は宣言されています型を持ちint、許可されている場所ならどこにでも現れる定数として。」つまり、列挙型定数は任意のint値であり、int型を持ちます。定義された列挙型変数の結果の型は、可能な限りすべてを可能にする限り、、またはになりcharますintunsigned int列挙型の定数。このようenumsに、例の両方は整数オーバーフローを必要とするため、未定義です。最初の定数は明示的に不正です。

于 2013-03-08T21:33:42.183 に答える
0

ISO C は、整数を列挙値として指定します。

コンパイラで許可されている場合 (および GCC と Clang が許可している場合)、INT_MIN は完全に適切な値です。

コンパイラが指定されたインデックスを許可しない場合は、エラーを発行する必要があります。

明示的に要求された INT_MIN は問題ないが、INT_MAX の前任者からの自動増加値が警告を発行する理由は、標準が+1動作を必要とするためです。

于 2013-03-08T21:47:52.437 に答える