10

a当我尝试为类型变量分配不正确的值时,为什么编译器不抱怨enum answer

#include <stdio.h>

int main()
{
    enum answer {NO, YES};
    enum gender {MALE, FEMALE};

    enum answer a = 5; /* Assign an invalid value. */
    printf("answer: %d\n", a);

    a = MALE; /* Assign a value of wrong type */
    printf("answer: %d\n", a);

    return 0;
}

这是输出:

$ gcc -std=c99 -pedantic -Wall -Wextra enum.c 
$ ./a.out
answer: 5
answer: 0

如果enum不会导致类型检查,那么将语法设置为:

enum [identifier] {enumerator-list}

我使用answerandgender作为我的枚举的标识符。允许这种语法有什么意义?

我的意思是这段代码可以很好地写成

enum {NO, YES};
enum {MALE, FEMALE};

允许这种语法有什么意义?

enum answer {NO, YES};
enum gender {MALE, FEMALE};
4

3 回答 3

7

a当我尝试为类型变量分配不正确的值时,为什么编译器不抱怨enum answer

因为在 C 中, anenum实际上等同于 an int。它像它一样被标准化,只是太多的程序依赖于这种行为来改变它。

在 C++ 中,它们是不同的类型,编译器会抱怨:

$ g++ -Wall -Wextra a.c
a.c: In function 'int main()':
a.c:8:24: error: invalid conversion from 'int' to 'main()::answer' [-fpermissive]
a.c:11:14: error: cannot convert 'main()::gender' to 'main()::answer' in assignment

允许这种语法有什么意义?

我的快速猜测是前向兼容性。

于 2012-08-12T15:13:00.530 回答
4

C 将值直接公开enumeration为整数,而在 C++enum中是实类型。因此在 C++enum中会导致类型检查,而在 C 中 enum 仅表示 int 类型的常量。因此整数和枚举值可以在所有算术运算中混合使用。

于 2012-08-12T15:19:47.767 回答
0

假设:

enum answer {NO, YES};

enum gender {MALE, FEMALE};

和:

enum answer bla = YES; 
enum gender blop = MALE;
int bip = 0;

虽然 C 标准没有要求,但它允许实现在以下情况下发出警告:

bla = blop;

bip =  bla;

请注意,enum类型是算术类型,并且始终允许在不同算术类型的对象之间进行分配,但实现仍然可以自由警告。正如一些人提到的评论,enumC++ 的类型规则是不同的。

编辑:另一个例子:

enum ans {
    YES,
    NO,
    MAYBE
};


enum ans a = /* initializer */;

switch (a)
{
    case YES:
        break;
    case NO:
        break;
}

使用-Wall(即-Wswitch), gcc能够警告:

tst.c:15:5:警告:枚举值“可能”未在开关中处理

如果你有:

enum {
    YES,
    NO,
    MAYBE
};

int a = /* initializer */;

gcc将无法警告。因此,实际上使用enum类型而不是仅使用enum常量有助于静态分析器工具。

于 2012-08-12T16:56:07.860 回答