2016-11-26 140 views
1

我想typdef一個枚舉是另一個typdef枚舉的擴展。我可以typdef一個枚舉是另一個typdef枚舉的擴展嗎?

一個typedef枚舉有4個元素(因爲我只在結構中有2個位來存儲它的值),另一個具有相同的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; 
    } 
} 

我可以的typedef一個case_ext_t包括所有case_t額外的那些元素,再加上?

另外,我可以定義只是更大的typedef枚舉case_ext_t,但只使用其前4個元素,當它存儲它的2位結構?

+1

您**可以**擴展另一個'enum'的值。將第二個「enum」的第一個值設置爲第一個「enum」+1的最後一個值。然後,當您引用任何這些'enum'標識符時,它將是唯一的。雖然'typedef'和'enum'爲什麼不能迴避我。吻。 –

+0

@Waether Vane>爲什麼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時使用沒有前綴的宏,並在聲明「extended」枚舉時使用另一個前綴。您可以在宏後添加其他枚舉。

我的示例打印:Base 1, ext 1, 4

2

我可以的typedef一個case_ext_t包括所有case_t額外的那些元素,再加上?

不,你不能。如果標識符在給定的翻譯單元中被聲明爲枚舉常量,那麼它必須是翻譯單元中該標識符的唯一聲明(C2011,6.7/5)。因此,如果在相同的翻譯單元中使用兩個枚舉類型,除了不完整的類型,那麼它們不能具有任何共同的枚舉常量。

另外,我可以定義只是更大的typedef枚舉case_ext_t,但只使用其前4個元素時,它存儲它的結構2位?

否。位域聲明可能不指定比字段的基本類型實際具有更多位(C2011,6.7.2.1/4)。此外,無論指定的位數是多少,它都是實現定義的,無論您是否可以使用枚舉類型作爲位域的聲明類型,保證允許的唯一類型是_Bool,signed intunsigned int(C2011,6.7.2.1/5)。

我認爲最好的方法是聲明你的位域爲unsigned int類型,並聲明只有較大的枚舉類型:

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

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

使用invalid_case適當的測試,以保障分配到a_word.case_


或者,你真的需要使用位域嗎?這似乎引起了很多你的驚愕,而這一切都不值得一提。爲什麼不簡單使用

struct { 
    case_t case_; 
    unsigned other_stuff; 
} a_word; 

+0

>您真的需要使用位域嗎? ...是的:這是一個嵌入式應用程序,並且逐個定義的單詞被系統中的其他組件使用。 –

+1

@DavideAndrea,在這種情況下,請注意'struct a_word'可能不能與一個普通的16位整數互換。特別是,編譯器不需要在16個連續位中設置兩個位域,如果是這樣,則它們在這16個位內的相對順序是實現定義的。而且,整個結構可能會有拖尾填充。 –

+0

我確實處理了這個細節(帶有「packed」屬性)。儘管如此,謝謝你的高舉。 –