2015-02-09 137 views
20

我正在与一个嵌入式设备交换数据包,我真的希望能够在数据包定义的子字节部分使用枚举。但我不能猜测,可能工作语法,我怀疑这是不可能的,因为我不能工作,如何在C++中声明的部分字节的亚型:是否可以在C++ 11中指定枚举的位宽?

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 { ... 

无论是那些编译,我有查找涉及位字段和枚举的文档时遇到问题,使我怀疑没有。在我花几个小时寻找之前,我试图做甚么?


编辑:升级到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的实验工具列表,所以我需要从源代码来构建。我想我现在只是在解决这个问题。感谢你的帮助。

+3

谁降低了这个数字?我们很少看到更完美的问题。 – Potatoswatter 2015-02-09 02:20:31

+2

...还有,在嵌入式设备上使用现代C++的荣誉。 – Potatoswatter 2015-02-09 02:22:00

+0

谢谢。我习惯于Delphi,所以它看起来很自然,特别是当我们对嵌入式输出(Delphi,C++,ObjectiveC和Java。)的消费者进行多边测试时,显然是出于某种原因。让每个人的代码尽可能相似地读取并使用任何可用的安全类型更容易。 – 2015-02-09 02:29:14

回答

12

您发布的代码应该被最近的编译器接受。你可以看到这个bug报告,其中修复应该发生:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51242

在今天的GCC,警告仍然应该发出。在叮当中,你什么也看不到。

+1

@CodeAbominator:第一个注释包含一个与您的代码基本相同的测试用例。 – 2015-02-09 03:02:33

+0

有趣的是,这个bug已经过去了一个多年,正是我想要做的。该标准甚至提到“一个位域应该具有整型或**枚举类型**(3.9.1)”。不幸的是,它看起来不会很快得到修复。 – 2015-02-09 03:11:56

+0

来自标准的更多信息的另一个错误。看起来更可能是这样的:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56566 – 2015-02-09 21:53:34

8

没有,有没有办法typedef C++中的位字段,甚至不枚举类型。

位域岬是的成员变量声明的属性,它不是由该类型系统所支持的。

但是,您的第一个例子非常好。正如比尔说,这是一个错误的GCC,并作为GCC开发note,这只是一个警告,因为2013年的解决方法是使用int path : 3;和枚举值转换,或者不使用enum可言。

+0

谢谢。显然我很担心,但确认它是有用的。 – 2015-02-09 02:20:24

0

它在Debian上起作用至少是g ++ 4.8,所以我也假设在Ubuntu上。

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

相关问题