2016-08-10 24 views
2

我有這樣如何避免在Enum中使用十六進制的迂腐警告?

typedef enum { 
    FIRST, 
    SECOND, 
    THIRD = 0X80000001, 
    FOURTH, 
    FIFTH, 
} STATUS; 

我得到一個迂腐的警告,因爲我在編譯的選項-Wpedantic我的文件枚舉:

警告:ISO C限制枚舉值「廉政範圍'[-Wpedantic]

我發現它發生以來,因爲當我將十六進制值0X80000001轉換爲整數時,它超出了無符號整數限制。我的目的是在沒有此警告的情況下將連續的十六進制值作爲枚舉中的狀態。 我不能使用這些宏,因爲這將違反首先使用枚舉的目的。哪些代碼更改會避免此警告?

+0

是不是'enum'保留關鍵字? –

+0

是的,它創建一個枚舉。 – Caw

+1

@sunqingyao是的。它應該用來創建一個枚舉,就像OP一樣。 – StoryTeller

回答

4

枚舉常量保證與(簽名)int的大小相同。顯然你的系統使用32位int,所以大於0x7FFFFFFF的無符號十六進制文字將不適合。

所以這個警告不僅僅是「迂腐」,它暗示着一個可能嚴重的錯誤。請注意,GCC中的-pedantic確實是而不是的意思是「挑剔,給我不重要的警告」,而是「確保我的代碼實際上遵循C標準」。

看來你想做一個位掩碼或硬件地址或其他硬件相關的編程列表。 enum不適合執行此類任務,因爲在與硬件相關的編程中,您很少想使用簽名類型,但始終未使用簽名類型。

如果你必須有一個安全和便攜的程序,那麼沒有優雅的方式來做到這一點。 C是一種有很多缺陷的語言,enum由標準定義的方式就是其中之一。

一個解決辦法是使用某種形式的「窮人的枚舉」,如:

typedef uint32_t STATUS; 

#define THIRD 0X80000001 

如果你還必須有一個枚舉的增加類型安全,那麼你可能使用結構:

typedef struct 
{ 
    uint32_t value; 
} STATUS; 

或者,也可以聲明一個常量數組並使用枚舉來定義數組索引。可能是最乾淨的解決方案,但需要一點額外的開銷:

typedef enum { 
    FIRST, 
    SECOND, 
    THIRD, 
    FOURTH, 
    FIFTH, 
    STATUS_N 
} STATUS; 

const uint32_t STATUS_DATA [STATUS_N] = 
{ 
    0, 
    1, 
    0X80000001, 
    0X80000002, 
    0X80000003 
}; 
+0

'枚舉常量保證與(signed)int相同大小標準說:'每個枚舉類型應與char,有符號整數類型或無符號整數類型兼容。類型的選擇是實現定義的,但應能夠表示枚舉的所有成員的值。「這聽起來對我來說是一個衝突。 – 4386427

+5

@ 4386427的確,這是我正在談論的C語言缺陷的一部分。一個_umeumeration常數保證和'int'(6.7.2.2/3)是一樣的類型,但是_enumeration類型_(變量)可以是任何上述類型(6.7.2.2/4)。這很愚蠢,但它是一個衆所周知的缺陷。 – Lundin