为什么C编译器允许从uint16_t到枚举类型的静默强制转换?
我的印象是,将整数类型传递到需要枚举参数的函数中是一个错误,或者至少是一个警告。但是我用为什么C编译器允许从uint16_t到枚举类型的静默强制转换?,c,enums,language-lawyer,C,Enums,Language Lawyer,我的印象是,将整数类型传递到需要枚举参数的函数中是一个错误,或者至少是一个警告。但是我用-Wall-Wextra-Werror试过了,没有警告。我错过了什么?C标准允许这样做吗 也许对我的直接使用来说更重要的是,是否有gcc或clang的编译器选项对此进行警告?将enum类型作为形式参数的目的是作为限制有效enum值的契约 #include <stdint.h> typedef enum { FLAG_A = 1, FLAG_B = 2, FLAG_C =
-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
}
#包括
类型定义枚举{
标志A=1,
标志_B=2,
标志C=4
}旗帜;
uint16_t flags=0;
无效清除标志(标志)
{
旗子&=~旗子;
}
void doit()
{
clearFlags(flags);//这不应该是正常的;flags的类型是uint16\u t
}
枚举类型与整数类型兼容,因此将整数传递给需要enum
作为参数的函数是有效的
有关枚举说明符的第6.7.2.2p4节规定:
每个枚举类型应与签名字符兼容
整数类型,或无符号整数类型。选择
类型由实现定义,但应能够表示所有成员的值
枚举。枚举类型不完整,直到 紧接着终止枚举数列表的
}
声明,然后完成
兼容类型的定义见第6.2.7p1节:
如果两种类型的类型相同,则它们具有兼容的类型
这意味着一个枚举类型实际上与一个整数类型具有相同的类型。这是合法的(如其他答案中所述)。编译器可能(但不是必须)警告:
为枚举类型的对象指定值,而不是通过分配作为该类型成员的枚举常量、具有相同类型的枚举对象或返回相同枚举类型的函数的值
-附件I,常见警告。@ason S枚举在C中是整数类型。请阅读。我相信它在C11中是合法的(而不是在C++中)。仍然有一些编译器选择警告“混合枚举和整数”类型,哪些编译器?有没有办法在gcc或clang中打开该警告?与之相关(但不完全相同)!!!!即使传入的值不是
枚举中的有效值
@JasonS:Nothing限制enum
s仅包含给定标签的值。事实上,通常使用enum
列出标志掩码,期望实际值为一个或多个标记值的按位或。关键字“兼容”也是如此吗?C标准中“兼容”的含义是什么?@rici那么,如果一个单独的类型enum MyEnum
的行为就像一个整数类型,那么它的意义是什么?如果我有一个函数void doSomething(enum MyEnum e)
如果e
可以是任何“兼容类型”的任意整数值,我为什么要麻烦呢?@jasonS:这是一个合理的问题,我没有答案。但是,那么,我也没有责任;40多年前设计C的不是我。你可以使用C++,它可以让你定义更接近你理想的EnUM类。我能说的是,这不是C的工作方式,大概从永远都是这样,现在不会改变。