I'm trying to generate an enum compilation error by runing the following code in VS2010:
我试图通过在VS2010中运行以下代码来生成枚举编译错误:
typedef enum {F,E,D,C,B,A} grade_t;
main(){
grade_t james=E+A;
printf("%d",james);
}
however it still runs and prints 6 to the screen. As far as I know james should be assigned only the enum defined consts. I also get the expected compilation error while writing the above assignment:
但它仍然运行并在屏幕上打印6。据我所知,james应该只分配枚举定义的consts。在编写上述赋值时,我也得到了预期的编译错误:
IntelliSense: a value of type "int" cannot be used to initialize an entity of type "grade_t"
1) Why does it run even though it is out of range?
2) Does it mean that some compilation errors might be considered as logic errors?
1)为什么即使它超出范围也会运行? 2)是否意味着某些编译错误可能被视为逻辑错误?
2 个解决方案
#1
Enums are just integers. The C standard states that an enum variable should correspond to one of the standard integer types, usually char
, int
or unsigned int
. The C standard (6.7.2.2) is, bluntly put, retarded and allows enum variables to have an implementation-defined type while enum constants (F, E, D etc) must have type int. This is a "bug"/inconsistency in the standard itself.
枚举只是整数。 C标准声明枚举变量应该对应于标准整数类型之一,通常是char,int或unsigned int。直接放置C标准(6.7.2.2),并允许枚举变量具有实现定义类型,而枚举常量(F,E,D等)必须具有int类型。这是标准本身的“错误”/不一致。
So grade_t james=E+A;
is completely equivalent to grade_t james=(int)E+(int)A;
. Since enum constants must be type int, there is no possibility for the compiler to do any type checks, nor does the standard mandate any. It does not look at the contents of this int
value to do some sort of sanity check.
所以grade_t james = E + A;完全等同于grade_t james =(int)E +(int)A;。由于枚举常量必须是int类型,因此编译器不可能进行任何类型检查,标准也不能强制执行任何类型检查。它不会查看此int值的内容来进行某种健全性检查。
And then you store the result of the integer addition, which is of type int
, inside a grade_t
variable. Here the compiler could yield a warning, which your compiler seems to do. But it is not required to do so. C has very little in the way of type safety and out-of-range checks.
然后在grade_t变量中存储整数加法的结果,类型为int。在这里,编译器可能会产生警告,编译器似乎会这样做。但并不要求这样做。 C在类型安全和超出范围检查方面几乎没有什么作用。
2) Does it mean that some compilation errors might be considered as logic errors?
2)是否意味着某些编译错误可能被视为逻辑错误?
Not sure what you mean here. You are not supposed to get any compiler error from the code posted. Please note that Visual Studio is poor at following the C standard and it is a C++ compiler by default. C++ has stricter type rules than C, so if you compile C code in C++, you'll get more warnings/errors.
不确定你的意思。您不应该从发布的代码中获得任何编译器错误。请注意,Visual Studio在遵循C标准方面很差,默认情况下它是C ++编译器。 C ++具有比C更严格的类型规则,因此如果您在C ++中编译C代码,您将获得更多警告/错误。
#2
this is what is happening
这就是正在发生的事情
typedef enum {F,E,D,C,B,A} grade_t;
is equal to
等于
typedef enum {
F = 0 ,
E = 1,
D = 2,
C = 3,
B = 4,
A = 5
} grade_t;
so any where you use A,B,C,D,E,F the equivalend enum value is selected ... so
所以在你使用A,B,C,D,E,F的地方选择等值枚举值......所以
A + E = 1 + 5 = 6
A + E = 1 + 5 = 6
so you can see that there is nothing which should generate an error.
所以你可以看到没有什么应该产生错误。
#1
Enums are just integers. The C standard states that an enum variable should correspond to one of the standard integer types, usually char
, int
or unsigned int
. The C standard (6.7.2.2) is, bluntly put, retarded and allows enum variables to have an implementation-defined type while enum constants (F, E, D etc) must have type int. This is a "bug"/inconsistency in the standard itself.
枚举只是整数。 C标准声明枚举变量应该对应于标准整数类型之一,通常是char,int或unsigned int。直接放置C标准(6.7.2.2),并允许枚举变量具有实现定义类型,而枚举常量(F,E,D等)必须具有int类型。这是标准本身的“错误”/不一致。
So grade_t james=E+A;
is completely equivalent to grade_t james=(int)E+(int)A;
. Since enum constants must be type int, there is no possibility for the compiler to do any type checks, nor does the standard mandate any. It does not look at the contents of this int
value to do some sort of sanity check.
所以grade_t james = E + A;完全等同于grade_t james =(int)E +(int)A;。由于枚举常量必须是int类型,因此编译器不可能进行任何类型检查,标准也不能强制执行任何类型检查。它不会查看此int值的内容来进行某种健全性检查。
And then you store the result of the integer addition, which is of type int
, inside a grade_t
variable. Here the compiler could yield a warning, which your compiler seems to do. But it is not required to do so. C has very little in the way of type safety and out-of-range checks.
然后在grade_t变量中存储整数加法的结果,类型为int。在这里,编译器可能会产生警告,编译器似乎会这样做。但并不要求这样做。 C在类型安全和超出范围检查方面几乎没有什么作用。
2) Does it mean that some compilation errors might be considered as logic errors?
2)是否意味着某些编译错误可能被视为逻辑错误?
Not sure what you mean here. You are not supposed to get any compiler error from the code posted. Please note that Visual Studio is poor at following the C standard and it is a C++ compiler by default. C++ has stricter type rules than C, so if you compile C code in C++, you'll get more warnings/errors.
不确定你的意思。您不应该从发布的代码中获得任何编译器错误。请注意,Visual Studio在遵循C标准方面很差,默认情况下它是C ++编译器。 C ++具有比C更严格的类型规则,因此如果您在C ++中编译C代码,您将获得更多警告/错误。
#2
this is what is happening
这就是正在发生的事情
typedef enum {F,E,D,C,B,A} grade_t;
is equal to
等于
typedef enum {
F = 0 ,
E = 1,
D = 2,
C = 3,
B = 4,
A = 5
} grade_t;
so any where you use A,B,C,D,E,F the equivalend enum value is selected ... so
所以在你使用A,B,C,D,E,F的地方选择等值枚举值......所以
A + E = 1 + 5 = 6
A + E = 1 + 5 = 6
so you can see that there is nothing which should generate an error.
所以你可以看到没有什么应该产生错误。