C/gcc 中的枚举类型检查 [英] enum type check in C/gcc

查看:27
本文介绍了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 enums? 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的类型,以及两个叫做appleorange的枚举器.

declares three things: a type called enum fruit, and two enumerators called apple and orange.

enum Fruit 实际上是一个不同的类型.它与某些实现定义的整数类型兼容;例如,enum Fruit 可能与 intchar 甚至 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; };

structfruitstruct 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆