2016-11-26 15 views
1

別のtypdef列挙型の拡張である列挙型をtypdefしたいと思います。別のtypdef列挙型の拡張である列挙型をtypdefできますか?

1つのtypedef列挙型は4つの要素を持っています(なぜなら、その値を格納する構造体には2ビットしかないからです)。もう1つは同じ4要素を持ち、5番目の要素は構造体に格納されず無効な値をマークする)。

サンプルコード:

typedef enum { 
    case0, 
    case1, 
    case2, 
    case3, 
} case_t; 

typedef enum { 
    one_t,   // 0 through 3 <---HOW CAN I DO THIS? 
    invalid_case, // 4 
} case_ext_t 

struct { 
    case_t case_  :2; // 2 bits, for up to 4 cases 
    unsigned other_stuff:14; // 
} a_word; 

case_ext_t my_case = invalid_case; 
if (condition) { 
    my_case = case2; 
} 

if (my_case != invalid_case) { 
    switch (my_case) { 
     case case0: {....} break; 
     case case1: {....} break; 
     case case2: {....} break; 
     case case3: {....} break; 
    } 
} 

は、私はすべてのcase_tの要素に加え、追加のものが含まれてcase_ext_tをtypedefはできますか?

また、より大きなtypedef列挙型case_ext_tを定義することはできますが、構造体の2ビットを格納するときは最初の4要素のみを使用しますか?

+1

あなたは**別のもので 'enum'の値を拡張することができます**。 2番目の 'enum'の最初の値を最初の' enum' +1の最後の値に設定します。そして、それらの 'enum'識別子のいずれかを参照すると、それは一意になります。なぜ、「typedef」というenumが私を逃すのですか?キッス。 –

+0

@Waether Vane>なぜtypedef enumが私を見捨てるのですか...私はそれらを広範囲に使います。たとえば、上記の私のコードを参照してください:私は列挙型をtypedefし、構造体( "符号なし"の代わりに)の要素の型としてそれを使用する –

答えて

1

列挙型を別の値で拡張することはできません。

しかし、あなたは、あなたがやりたいことには少しマクロトリックを使用することができます。

#include <stdio.h> 

#define base_enum(prefix) prefix##case0,prefix##case1,prefix##case2,prefix##case3 

typedef enum { 
    base_enum() 
} case_t; 

typedef enum { 
    base_enum(ext_), 
    invalid_case, // 4 
} case_ext_t; 


int main() 
{ 
    printf("Base %d, ext %d, %d\n",case1,ext_case1,invalid_case); 
return 0; 
} 

だから、あなたはあなたのベースを定義するには、接頭辞を使用して、マクロの中に列挙する。

case_tと宣言するときは接頭辞なしのマクロを使用し、 "拡張"列挙型を宣言するときは別の接頭辞を使用します。マクロの後に他の列挙型を追加することができます。

私の例のプリント:Base 1, ext 1, 4

2

は、私はすべてのcase_tの要素に加え、追加のものが含まれてcase_ext_tをtypedefはできますか?

いいえ、できません。識別子が与えられた翻訳単位の列挙定数として宣言されている場合、翻訳単位(C2011、6.7/5)でその識別子の唯一の宣言でなければなりません。したがって、2つの列挙型が同じ変換単位で使用される場合、不完全な型を除いて、それらは共通の列挙定数を持つことはできません。

また、より大きなtypedef列挙型case_ext_tを定義することはできますが、構造体の2ビットを格納するときに最初の4要素のみを使用しますか?

いいえビットフィールド宣言では、実際にフィールドの基本型(C2011,6.7.2.1/4)より多くのビットを指定できません。さらに、指定されたビット数にかかわらず、列挙型をビットフィールドの宣言型として使用できるかどうかは実装定義されています。許可されることが保証されている唯一のタイプは、_Bool,signed int、およびunsigned int(C2011,6.7.2.1/5)です。 a_word.case_への割り当てを保護するためにinvalid_caseため

typedef enum { 
    case0, 
    case1, 
    case2, 
    case3, 
    invalid_case, // 4 
} case_t; 

struct { 
    unsigned case_:2; 
    unsigned other_stuff:14; 
} a_word; 

を使用して、適切なテスト:

は、私はあなたの最善の策は、タイプ unsigned intとしてあなたのビットフィールドを宣言するために、そして唯一の大きな列挙型を宣言することだと思います。


また、実際にビットフィールドを使用する必要がありますか?それはあなたの多くの驚きを引き起こしているようですが、その悩みは価値があることはまったく明らかではありません。単に使用しないでくださいなぜ

struct { 
    case_t case_; 
    unsigned other_stuff; 
} a_word; 

+0

>本当にビットフィールドを使用する必要がありますか? ...はい:これは組み込みアプリケーションであり、定義されているとおり、ビット単位で、システム内の他のコンポーネントによって使用されています。 –

+1

@DavideAndreaの場合、 'struct a_word'はプレーンな16ビット整数と互換性がないかもしれないことに注意してください。特に、コンパイラは、2つのビットフィールドを16個の連続したビットでレイアウトする必要はなく、そうであれば、それらの16ビット内の相対順序はインプリメンテーション定義です。さらに、構造体全体に後続のパディングがある可能性があります。 –

+0

私はその詳細を( "packed"属性で)扱います。それでも、頭をアップしてくれてありがとう。 –