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

Is it possible to specify the bit width of an enum in 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;

无法编译,因为您无法将 8 位枚举放入 3 位字段。在确切错误中编辑:

<anonymous struct>::path’ is too small to hold all values
   of ‘enum class MyNamespace::communication_path_t’ [-Werror]

我想做的是这样的:

enum class communication_path_t : uint8_t : 3 { ...

typedef uint8_t:3 three_bit_int_t;
enum class communication_path_t : three_bit_int_t { ...

这些都不编译,而且我找不到同时引用位字段和枚举的文档,这让我怀疑有 none。在我花几个小时寻找之前,我尝试做的事情是否可行?


编辑:升级到 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]

然后更改我的构建链以使用 "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;

看来我需要 5.0,而且它不在 Ubuntu 实验工具列表中,所以我需要从源代码构建。我想我现在只能接受解决方法。感谢大家的帮助。

不,没有办法 typedef C++ 中的位域,即使是枚举类型也不行。

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

但是,您的第一个示例非常好。正如 Bill 所说,这是一个 GCC 错误,作为 GCC 开发人员 note,它只是自 2013 年以来的一个警告。解决方法是使用 int path : 3; 并转换枚举值,或者不使用enum 完全没有。

您发布的代码应该被最新的编译器所接受。您可以在本应进行修复的位置查看此错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51242

在今天的gcc中,应该还是会发出警告。在 clang 中,你应该什么也看不到。

它至少适用于 debian 上的 g++ 4.8,所以我假设也适用于 ubuntu。

编译器只给出警告,这种情况下的错误是由 -Werror 编译器选项引起的。为 overflow 配置 -Werror 是个好主意,因为在分配不适合位域的枚举值时会报告这一点。