簡體   English   中英

為什么 C 編譯器允許從 uint16_t 靜默轉換為枚舉類型?

[英]Why does the C compiler allow silent casting from uint16_t to an enum type?

我的印象是,將整數類型傳遞給需要枚舉參數的函數是錯誤或至少是警告。 但是我在編譯器資源管理器中使用-Wall -Wextra -Werror ,並且沒有警告。 我錯過了什么? C 標准允許這樣做嗎?

也許對我的直接使用更重要的是,是否有 gcc 或 clang 的編譯器選項來警告這一點? enum類型作為正式參數的目的是作為一種限制有效enum值的合同。

#include <stdint.h>

typedef enum {
    FLAG_A = 1,
    FLAG_B = 2,
    FLAG_C = 4
} FLAG;

uint16_t flags = 0;

void clearFlags(FLAG flag)
{
    flags &= ~flag;
}

void doit()
{
    clearFlags(flags);   // this should not be ok; flags is type uint16_t
}

枚舉類型與整數類型兼容,因此將整數傳遞給需要enum作為參數的函數是有效的。

關於枚舉說明符的C 標准第 6.7.2.2p4 節指出:

每個枚舉類型應與char 、有符號整數類型或無符號整數類型兼容。 類型的選擇是實現定義的,但應能夠
代表全體成員的價值觀
枚舉。 枚舉類型在緊接在終止枚舉器聲明列表的}之后是不完整的,然后是完整的。

兼容類型的定義在 6.2.7p1 節:

如果它們的類型相同,則兩種類型具有兼容類型

所以這意味着枚舉類型實際上與整數類型之一具有相同的類型。

這是合法的(正如其他答案中已經解釋的那樣)。 編譯器可能(但不是必須)警告:

值被賦予枚舉類型的對象,而不是通過分配作為該類型成員的枚舉常量,或具有相同類型的枚舉對象,或返回相同枚舉類型的函數的值

— 附件 I,常見警告

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM