是否可以在 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 是个好主意,因为在分配不适合位域的枚举值时会报告这一点。
我正在与嵌入式设备交换数据包,我真的很想也能在数据包定义的子字节部分使用枚举。但我猜不出可能有效的语法,我怀疑这是不可能的,因为我不知道如何在 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 是个好主意,因为在分配不适合位域的枚举值时会报告这一点。