13

新しいプラットフォームに移植するコードがいくつかありますが、2 つの異なる列挙子リストの 2 つの列挙子を比較するとエラーが発生し始めました。これについてエラーが発生する理由がわかりません。

C 仕様 (6.7.2.2) の列挙仕様セクションには、次のように記載されています。

列挙子リスト内の識別子は、int 型の定数として宣言され、許可されている場所であればどこにでも表示できます。127) = を持つ列挙子は、その列挙定数を定数式の値として定義します。最初の列挙子に = がない場合、その列挙定数の値は 0 です。

したがって、int 定数と同じように enum メンバーを使用できるはずです。この小さなサンプル プログラムでは:

enum first {
  a,
  b
};

enum second {
 c,
 d
};

int main(){
    enum first myf = a;
    enum second mys = c;

    if(myf == mys)
        printf("same value\n"); 
    return 0;
}

でコンパイルするgcc -Wall -Werrorと、次のメッセージが表示されます。

エラー: 'enum first' と 'enum second' の比較 [-Werror=enum-compare]

myfandの両方を型キャストすると、コンパイラが満足することはわかっていmysますint。ちょうど、andintの値をいくつかの s に設定して比較を行うことができるのと同じです。しかし、警告を取り除くためにこれらのいずれかを実行する必要があるのはなぜですか? そもそもなぜこの警告が存在するのですか?これを行うには、私が見ていない何らかの危険があるに違いありません。myfmys


注:
この enum-compare フラグに関する gcc のドキュメントを読みましたが、多くのことは語られていません。

-Wenum-compare
異なる列挙型の値の比較について警告します。C++ では、条件式の列挙型の不一致も診断され、デフォルトで警告が有効になっています。C では、この警告は -Wall によって有効になります。

4

4 に答える 4

17

これは、標準準拠の問題による警告ではなく、「正しくないように見える」警告の 1 つです。列挙型の典型的な使用法を考えると、そのような比較を行うことは多くの場合あまり意味がありません。例えば:

enum Day {
  Sunday,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday
};

enum Month {
  January,
  February,
  March,
  April,
  May,
  June,
  July,
  August,
  September,
  October,
  November,
  December
};

enum Day day = Wednesday;
enum Month month = April; 

if (day == month) { ... }

これは true と評価されますが、一般に比較はあまり意味がありません。あなたがそれを意図していることがわかっている場合、あなたが指摘したように、型キャストはコンパイラを納得させます。

于 2013-04-02T19:44:22.240 に答える
2

if((int)myf == (int)mys)

それはそれを行う必要があります。しかし、それは汚い習慣です。両方の列挙型が同じグループの異なる「バージョン」である場合にのみ使用してください。たとえば、新しいものには最後に新しいキーワードが含まれます。

于 2013-04-02T19:56:28.143 に答える
2

警告フラグがオンになっているため、警告しています。フラグの説明では、それが存在する理由は説明されていませんが、通常はエラーであるため、異なる列挙型間の偶発的な比較を防ぐために存在すると想定するのがおそらく安全です。

さらに、定数を int できるのと同じように列挙値を使用できることは正しいです。そして、あなたが言った場合if (myf == c)、それはおそらく警告をスローしなかったでしょう(私は実験していないため、GCCは正直にその警告でやりたいことを何でもできますが、技術的cには単なる整数定数であり、タイプenum second)。ただし、代わりに、異なる列挙型の 2 つの値を明示的に比較しています。

于 2013-04-02T19:42:35.497 に答える
1

それは警告ですが、 -Wall -Werror でコンパイルしたため、すべての警告はエラーとして扱われます残りの場合、同様の質問で何かを見つけることができます。

2 つの異なる列挙型を比較す​​るときに警告を回避する正しい方法はありますか?

よろしく

于 2013-04-02T19:49:56.950 に答える