是否可以在C++ 11中指定枚举的位宽?

Cod*_*tor 20 c++ gcc c++11

我正在与嵌入式设备交换数据包,我真的希望能够在数据包定义的子字节部分使用枚举.但我无法猜测可能有效的语法,我怀疑它是不可能的,因为我无法弄清楚如何在C++中声明部分字节的子类型:

enum class communication_path_t : uint8_t  { 
    Ethernet = 0, Wifi = 1
};

typedef struct {
    communication_path_t pathByte;  // works, uses one byte
    // ... 
    // single byte split three ways
    uint8_t retryCount : 3;
    communication_path_t path : 3;  // compile error
    uint8_t deviceType : 2;
} packet_t;
Run Code Online (Sandbox Code Playgroud)

这不能编译,因为你无法将8位枚举放入3位字段.编辑确切的错误:

<anonymous struct>::path’ is too small to hold all values
   of ‘enum class MyNamespace::communication_path_t’ [-Werror]
Run Code Online (Sandbox Code Playgroud)

我想做的是这样的事情:

enum class communication_path_t : uint8_t : 3 { ...
Run Code Online (Sandbox Code Playgroud)

要么

typedef uint8_t:3 three_bit_int_t;
enum class communication_path_t : three_bit_int_t { ...
Run Code Online (Sandbox Code Playgroud)

这些都没有编译,我找不到引用位域和枚举的文档,让我怀疑没有.在我花几个小时看之前,我正在努力做甚至可能吗?


编辑:升级到g ++ - 4.9不能解决问题.它非常轻松,只是:

sudo apt-get install g++-4.9
g++-4.9 --version

g++-4.9 (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2
GCC 4.9.2 released [2014-10-30]
Run Code Online (Sandbox Code Playgroud)

然后改变我的构建链使用"g ++ - 4.9"而不是"g ++".不幸的是我得到了同样的错误:

g++-4.9 -Dlinux -std=c++11 -pthread (...) ../common/LogPacketBreakdown.cpp
In file included from ../common/LogPacketBreakdown.cpp:12:0:
../common/PacketInfo.h:104:50: error: ‘Digiflex::<anonymous
    struct>::communicationPath’ is too small to hold all values of 
    ‘enum class Digiflex::communication_path_t’ [-Werror]
    communication_path_t communicationPath : 3;
Run Code Online (Sandbox Code Playgroud)

看起来好像我需要5.0并且不在Ubuntu实验工具列表中,因此我需要从源代码构建.我想我现在只能接受解决方法.感谢你的帮助.

Bil*_*nch 12

您发布的代码应该被最新的编译器接受.您可以看到此错误报告应该发生的修复:https://gcc.gnu.org/bugzilla/show_bug.cgi?id = 51242

在今天的gcc中,仍然应该发出警告.在clang中,你什么都看不到.


Pot*_*ter 8

不,没有办法typedef在C++中使用位域,即使使用枚举类型也是如此.

Bitfield-ness是成员变量声明的属性,类型系统根本不支持它.

但是,你的第一个例子非常好.正如比尔所说,这是一个GCC错误,正如海湾合作委员会的开发人员所指出的那样,这只是2013年以来的警告.解决方法是使用int path : 3;和转换枚举值,或者根本不使用enum.