c - 为什么 C 编译器允许从 uint16_t 静默转换为枚举类型?

标签 c enums language-lawyer

我的印象是,将整数类型传递到需要枚举参数的函数时是一个错误,或者至少是一个警告。但我在Compiler Explorer中尝试过使用 -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 standard 第 6.7.2.2p4 节关于枚举说明符状态:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of
representing the values of all the members of the
enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.

兼容类型的定义位于第 6.2.7p1 节:

Two types have compatible type if their types are the same.

所以这意味着枚举类型实际上与整数类型之一具有相同的类型。

关于c - 为什么 C 编译器允许从 uint16_t 静默转换为枚举类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63565514/

相关文章:

ios - 带有字符串参数调用的 Swift 枚举函数,带有枚举类的参数

c++ - 部分专注于错误类型的非类型模板参数

swift - Swift 中的枚举和泛型

c++ - 为什么 std::unique_ptr operator* 抛出而 operator-> 不抛出?

当最大成员是原始类型时, union 是否可以大于最大成员?

c - 通过位操作获取 INT_MAX

c - 我如何从 C 函数的递归结构中获取数据?

c - 忽略 C 中的非小写字符

C 中的大小写可变宏

c - C 中的默认枚举值是否对所有编译器都相同?