2011-12-09 9 views
6

クイック質問:列挙スコープ

私のような列挙型を持っている場合:stuffAを参照するとき、ここで何が起こる

enum EnumA 
{ 
    stuffA = 0 
}; 
enum enumAA 
{ 
    stuffA = 1 
}; 

?私は、あなたがそれらをEnumA.stuffAEnumB.stuffAのようにjavaと同じように参照すると思ったが、そうではないようだ。任意の洞察力のための

おかげで迅速な回答のため

編集、ありがとう!

答えて

7

enums新しい範囲を導入しません。

例では、stuffAの名前の競合のために、2番目のenumがコンパイルされませんでした。

名前の衝突を避けるには、enumの要素に共通の接頭辞を付けるのが一般的です。異なるプレフィックスが異なる列挙型のために使用されるでしょう:

enum EnumA 
{ 
    EA_stuffA = 0 
}; 
enum EnumAA 
{ 
    EAA_stuffA = 1 
}; 
+0

もし私が上記のようなもの(狭い範囲)を達成したいのであれば、構造は私の唯一のベストベットでしょうか? – prelic

+0

何かを使う必要があります: 'enum enumA {enumA_stuffA = 0}; enum enumAA {enumAA_stuffA = 1}; ' –

5

列挙定数は、ラベル、タグ、および構造体/共用体メンバの名前空間と対比グローバルネームスペース(より正確には、通常の識別子名前空間、です)ので、2番目のstuffAにコンパイルエラーが発生します。

単一の翻訳単位で、同じ列挙名に2つの異なる値(2回指定された同じ値)を使用することはできません。

1

前述のように、stuffAが2回定義されているため、これはコンパイルされません。列挙型の値は、単純に列挙型(EnumA.stuffAではなく「stuffA」)によって参照されます。列挙型ではない型(整数など)でも使用できます。列挙型は、定数を定義する方法と同様に、intでこのように使用されることがあります。

+2

Cでは' enum'定数は標準の定義によって 'int'です。 –

3

既に述べたように、列挙定数は定義されている実際のスコープ内で一意でなければなりません。しかし、他の識別子と同様に、別のスコープでそれらを再定義することができます。例えば。

enum EnumA 
{ 
    stuffA = 0 
}; 

void func(void) { 
    enum enumAA 
    { 
    stuffA = 1 
    }; 
    // do something 
} 

となります。しかし、さまざまな範囲でのそのような再定義はしばしば目立たなくなり、十分に文書化されなければなりません。

+3

+1そして幸運にも '-Wshadow'のgccは警告を出します: 'stuffA'の宣言はグローバルな宣言を影にします。 –