在C

时间:2015-05-11 07:43:27

标签: c enums

我试图通过在VS2010中运行以下代码来生成枚举编译错误:

typedef enum {F,E,D,C,B,A} grade_t;
main(){
    grade_t james=E+A;
    printf("%d",james);
}

然而它仍然运行并在屏幕上打印6。 据我所知,james应该只分配枚举定义的consts。在编写上述赋值时,我也得到了预期的编译错误:

IntelliSense: a value of type "int" cannot be used to initialize an entity of type "grade_t"    

1)为什么即使超出范围也会运行? 2)是否意味着某些编译错误可能被视为逻辑错误?

2 个答案:

答案 0 :(得分:1)

枚举只是整数。 C标准规定枚举变量应对应于标准整数类型之一,通常为charintunsigned int。 C标准(6.7.2.2)被直接放置,延迟并允许枚举变量具有实现定义类型,而枚举常量(F,E,D等)必须具有 int 类型。这是标准本身的“错误”/不一致。

所以grade_t james=E+A;完全等同于grade_t james=(int)E+(int)A;。由于枚举常量必须是int类型,因此编译器不可能进行任何类型检查,标准也不能强制执行任何类型检查。它不会查看此int值的内容来进行某种健全性检查。

然后在int变量中存储整数加法的结果,类型为grade_t。在这里,编译器可能会产生警告,编译器似乎会这样做。但并不要求这样做。 C在类型安全和超出范围检查方面几乎没有。

  

2)是否意味着某些编译错误可能被视为逻辑错误?

不确定你的意思。您不应该从发布的代码中获得任何编译器错误。请注意,Visual Studio在遵循C标准方面很差,默认情况下它是C ++编译器。 C ++有比C更严格的类型规则,所以如果你用C ++编译C代码,你会得到更多的警告/错误。

答案 1 :(得分:0)

这就是正在发生的事情

typedef enum {F,E,D,C,B,A} grade_t;

等于

typedef enum {
    F = 0 ,
    E = 1,
    D = 2,
    C = 3,
    B = 4,
    A = 5
    } grade_t;

所以在任何你使用A,B,C,D,E,F的地方选择等值枚举值......所以

  

A + E = 1 + 5 = 6

所以你可以看到没有什么可以产生错误。