允许枚举的标识符有什么意义?

时间:2012-08-12 15:07:40

标签: c enums

当我尝试将不正确的值分配给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}

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

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

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

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

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

3 个答案:

答案 0 :(得分:7)

  

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

因为在C中,enum实际上等同于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
  

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

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

答案 1 :(得分:4)

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

答案 2 :(得分: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类型是算术类型,并且始终允许在不同算术类型的对象之间进行分配,但实现仍然可以自由发出警告。正如一些人提到的那样,对于C ++,enum类型的规则是不同的。

编辑:另一个例子:

enum ans {
    YES,
    NO,
    MAYBE
};


enum ans a = /* initializer */;

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

使用-Wall(即-Wswitch),gcc可以发出警告:

  

tst.c:15:5:警告:在交换机

中未处理枚举值'MAYBE'

如果你有:

enum {
    YES,
    NO,
    MAYBE
};

int a = /* initializer */;

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