【问题标题】:Can I typdef an enum that is an extension of another typdef enum?我可以 typedef 一个枚举,它是另一个 typedef 枚举的扩展吗?
【发布时间】:2016-11-26 20:48:02
【问题描述】:

我想键入一个枚举,它是另一个 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_t 的所有元素以及其他元素的 case_ext_t 吗?

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

【问题讨论】:

  • 可以enum 的值扩展为另一个。将第二个enum 的第一个值设置为第一个enum 的最后一个值+1。然后,当您引用任何 enum 标识符时,它将是唯一的。虽然为什么typedefenum 让我难以理解。亲吻。
  • @Waether Vane > 为什么 typedef an enum 让我无法理解...我广泛使用它们;例如,请参阅上面的代码:我 typedef an enum 然后将其用作结构中元素的类型(而不是“无符号”)

标签: c enums typedef


【解决方案1】:

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

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

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

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

?

【讨论】:

  • > 你真的需要使用位域吗? ... 是的:它是一个嵌入式应用程序,并且按照定义,这个词被系统中的其他组件逐位使用。
  • @DavideAndrea,在这种情况下,请注意struct a_word 可能无法与普通的 16 位整数互换。特别是,编译器不需要在 16 个连续位中布置两个位域,如果这样做,那么它们在这 16 个位中的相对顺序是实现定义的。此外,整个结构可能有尾随填充。
  • 我确实处理了那个细节(带有“打包”属性)。不过,感谢您的提醒。
【解决方案2】:

您不能使用另一个枚举的值来扩展枚举。

但是你可以使用一些宏技巧来做你想做的事:

#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

【讨论】:

    猜你喜欢
    • 2011-02-17
    • 1970-01-01
    • 2015-01-27
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多