2015-10-25 15 views
11

通常、列挙型は「定数整数」のグループを別の型として宣言するためのもので、何かを表します。例えば。このenum宣言は標準に準拠していますか?

enum Color {RED=0, BLUE, YELLOW}; 

これは明らかです。しかし、最近私は次のコードで会った。これは組み込みシステム用のコンパイラに含まれていました。

enum State {DISABLED=0, ENABLED=!DISABLED}; 

これはうまくいきました。それはブール型として振る舞いました。私の質問は、wheather(この構文)はANSI準拠ですか?

それが標準に準拠している場合は、なぜコンパイラは、内部ブール表現のための_Boolのようなものを定義した後、(C言語用)stdbool.hに彼らはありません:

#define bool _Bool 
... // here goes definitions of true and false 

代わりの

enum bool {false=0, true=!false}; 

どちらがきれいですか? C標準(識別子の6.2.1スコープ)によれば

+0

ANSI準拠ですか?それは私がしばらく聞いたことのないフレーズです。 –

+0

@DawidPi CとC++は異なる言語であり、このような微妙な問題は、両方の言語を同時にカバーする良い答えを得ることはほとんどありません。本当に両方の言語を知りたいのであれば、別々の質問としてそれらの質問をしてください。 – hvd

+0

@ AlanStokes編集に問題がある場合は、私がコメントで具体的に説明したように、それをコメントなしで元に戻すのはかなり失礼です。私はこれについてロールバック戦争に入りたいとは思わないが、懸念している限り、この質問は元の状態では広すぎて、適切な形にしようとする試みを妨害しようとするならば、 、私はちょうど閉会に投票します。 (もちろん、それは実際にはそれが実際に閉じられることを意味しません) – hvd

答えて

3

はい、宣言はCとC++の両方で完全に有効で移植性があります。 CおよびC++の両方において

は、この:

enum State {DISABLED=0, ENABLED=!DISABLED}; 

はこれに全く等価である:

enum State {DISABLED=0, ENABLED=1}; 

及びこれ:

enum State {DISABLED, ENABLED}; 

しかし微妙に異なる理由のために。 Cにおいて

(オペランドは0に等しい場合)、単項!オペレータが値0(オペランドは0に等しくない場合)、または1のいずれかで、タイプintの結果が得られます。 !xx == 0に相当します。 (0以外の値は条件として使用された場合はtrueと扱われますが、演算子のうちと==などは常に正確に0または1という結果になります)。列挙定数は常にタイプintです。値が指定されている場合は、必要に応じてintに変換されます。

(C 1999標準タイプ_Boolを添加するが、論理的に「ブール」値を生じるすべての演算子がまだタイプintの結果をもたらす。)

をC++で、単項!演算子の結果は、タイプboolであります。結果はfalseまたはtrueであり、Cの!演算子はそれぞれ0または1となります。 Cのように、値が指定されていれば、必要に応じて変換されます。 boolfalseおよびtrueはそれぞれ0および1に変換されます。

Cでは、列挙定数は常にタイプintです。 C++では列挙型です。この場合はenum Stateです。

同じ型宣言内の以前の列挙定数を参照するのは合法です。各列挙定数は、宣言された後に表示されます。以下のようなものについては

enum bool { false = 0, true = 1 }; 

より明確であること

enum bool { false = 0, true = !false); 

(Cで、それはC++で違法になります)、私は丁重に反対します。定数1は、Cに精通している人にとっては完全にはっきりしています。!falseとして書き直すのは役に立ちません。<stdbool.h>が(これらの日珍しい何か)が利用できないときに実際には、私が使用してきました:

typedef enum { false, true } bool; 

falsetrueがその正しい値が十分に明らかにされ私見与えられることになるという事実を。

なぜC99はそのようなenumの定義を使用しなかったのですか?それは、各列挙型が実装定義の整数型と互換性があるからです。 (gccの場合、通常はunsigned intまたはintです)委員会は、_Boolを他の整数型よりも低い変換ランクで区別するタイプにしたいと考えました。 (そして、彼らはboolを既存のコードを壊さずにキーワードにすることはできませんでした)

3

各列挙定数は、単に列挙リストにおけるその定義列挙の 外観

後に開始範囲を有します同じことがC++で有効です(3.3.2宣言のポイント)

5列挙子の宣言のポイントは、そのの直後ですだから、:[ここ

const int x = 12; 
{ enum { x = x }; } 

、列挙子xは定数 xの値で初期化され、すなわち12末端例例】

あなたは列挙子精細。列挙の次の列挙子の定義にすでに定義されている列挙子を使用することがあります。 C型_Boolとして

は、次いで、この

enum bool {false=0, true!=false}; 
ような列挙を定義することは意味がありません

C.

マニフェスト定数や列挙のいずれかが使用され、この規格の前にC 99で登場しました

タイプ_Boolには既に2つの値0と1があります。

6

はい、これは標準に準拠しています。

!DISABLEDは、有効な定数の式であり、これはすべてenumの値に必要です。DISABLEDが参照される時点で

enum State {DISABLED=0, ENABLED= (!DISABLED)}; 
//        ^^^^^^^^^^^ 

、コンパイラはその値を知っているので、それは、すなわち、!DISABLEDそれから誘導される式の値を計算することができます。それはENABLED=1を書こうとする素晴らしい方法です。

+0

そして、 'ENABLED = 1'(' = 1'でも冗長にすることができます) – Jack

+0

"' ENABLED = 1'を書こうとする素晴らしい方法です。コンパイラが 'ENABLED'と表示されたときにコードに直接パンチされています。 – user3629249

+0

@ user3629249:何? – Ryan