C/gcc 中的枚举类型检查 [英] enum type check in C/gcc
问题描述
请参阅下面的简单示例.当返回一个 enum
的函数被分配给不同 enum
的变量时,即使使用 gcc -Wall -pedantic
我也不会收到任何警告.为什么 C 编译器不能对 enum
进行类型检查?还是 gcc
特定的?我现在无法访问任何其他编译器来尝试它..
See the simple example below. When a function returning one enum
is assigned to a variable of a different enum
I don't get any warning even with gcc -Wall -pedantic
. Why is it not possible for a C compiler to do type checking on enum
s? Or is it gcc
specific? I don't have access to any other compiler right now to try it out..
enum fruit {
APPLE,
ORANGE
};
enum color {
RED,
GREEN
};
static inline enum color get_color() {
return RED;
}
int main() {
enum fruit ftype;
ftype = get_color();
}
推荐答案
本声明:
enum fruit {
apple,
orange
};
声明了三件事:一个叫做enum Fruit
的类型,以及两个叫做apple
和orange
的枚举器.
declares three things: a type called enum fruit
, and two enumerators called apple
and orange
.
enum Fruit
实际上是一个不同的类型.它与某些实现定义的整数类型兼容;例如,enum Fruit
可能与 int
、char
甚至 unsigned long long
兼容,如果实现选择,只要选择的类型可以代表所有的值.
enum fruit
is actually a distinct type. It's compatible with some implementation-defined integer type; for example, enum fruit
might be compatible with int
, with char
, or even with unsigned long long
if the implementation chooses, as long as the chosen type can represent all the values.
另一方面,枚举器是 int
类型的常量.事实上,有一个常见的技巧是使用裸 enum
声明来声明 int
常量而不使用预处理器:
The enumerators, on the other hand, are constants of type int
. In fact, there's a common trick of using a bare enum
declaration to declare int
constants without using the preprocessor:
enum { MAX = 1000 };
是的,这意味着常量 apple
,即使它被声明为 enum Fruit
定义的一部分,实际上并不是 enum 类型水果
.造成这种情况的原因是历史性的.是的,将枚举数设为该类型的常量可能更有意义.
Yes, that means that the constant apple
, even though it was declared as part of the definition of enum fruit
, isn't actually of type enum fruit
. The reasons for this are historical. And yes, it would probably have made more sense for the enumerators to be constants of the type.
在实践中,这种不一致很少很重要.在大多数情况下,离散类型(即整数和枚举类型)在很大程度上可以互换,而隐式转换通常会做正确的事情.
In practice, this inconsistency rarely matters much. In most contexts, discrete types (i.e., integer and enumeration types) are largely interchangeable, and the implicit conversions usually do the right thing.
enum fruit { apple, orange };
enum fruit obj; /* obj is of type enum fruit */
obj = orange; /* orange is of type int; it's
implicitly converted to enum fruit */
if (obj == orange) { /* operands are converted to a common type */
/* ... */
}
但结果是,如您所见,如果您使用与一种枚举类型关联的常量而您打算使用其他枚举类型,则编译器不太可能警告您.
But the result is that, as you've seen, the compiler isn't likely to warn you if you use a constant associated with one enumerated type when you mean to use a different one.
获得强类型检查的一种方法是将数据包装在结构中:
One way to get strong type-checking is to wrap your data in a struct:
enum fruit { /* ... */ };
enum color { /* ... */ };
struct fruit { enum fruit f; };
struct color { enum color c; };
structfruit
和 struct color
是不同且不兼容的类型,它们之间没有隐式(或显式)转换.缺点是您必须显式引用 .f
或 .c
成员.(大多数 C 程序员最初只是指望他们有能力把事情做好——结果喜忧参半.)
struct fruit
and struct color
are distinct and incompatible types with no implicit (or explicit) conversion between them. The drawback is that you have to refer to the .f
or .c
member explicitly. (Most C programmers just count on their ability to get things right in the first place -- with mixed results.)
(typedef
没有给你强类型检查;尽管有这个名字,它为现有类型创建了一个别名,而不是一个新类型.)
(typedef
doesn't give you strong type checking; despite the name, it creates an alias for an existing type, not a new type.)
(C++ 中的规则有点不同.)
(The rules in C++ are a little different.)
这篇关于C/gcc 中的枚举类型检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!