2015-02-09 63 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溢出因爲這樣分配不適合的位域枚舉值時會報一個好主意。

相關問題