我可以打造一个枚举,它是另一个typdef枚举的扩展吗?

时间:2016-11-26 20:48:02

标签: c enums typedef

我想说明一个枚举,它是另一个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;
    }
}

我可以输入一个case_ext_t,其中包含case_t的所有元素以及其他元素吗?

或者,我可以定义更大的typedef enum case_ext_t,但在存储2位结构时只使用前4个元素吗?

2 个答案:

答案 0 :(得分:2)

  

我可以输入一个case_ext_t,其中包含case_t的所有元素以及其他元素吗?

不,你不能。如果在给定的翻译单元中将标识符声明为枚举常量,则该标识符必须是翻译单元中该标识符的唯一声明(C2011,6.7 / 5)。因此,如果在同一个翻译单元中使用了两个枚举类型,除了不完整的类型,那么它们就不能有任何共同的枚举常量。

  

或者,我可以定义更大的typedef enum case_ext_t,但在存储2位结构时只使用前4个元素吗?

没有。位域声明可能不会指定比字段的基本类型实际具有的更多位(C2011,6.7.2.1/4)。此外,它是实现定义的,您是否可以使用枚举类型作为位字段&#39;无论指定的位数如何,都要声明类型;唯一可以保证允许的类型是_Boolsigned 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;

答案 1 :(得分: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时使用不带前缀的宏,并在声明&#34;扩展&#34;时使用另一个前缀枚举。您可以在宏之后添加其他枚举。

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