C将枚举与无效值进行比较
我想试着理解当我们比较枚举和无效值时编译器是如何工作的,以及程序在执行过程中做了什么 我在工作中发现了奇怪的源代码,不理解程序的行为,这并没有给我预期的结果 我写了下面的小程序来总结我的问题 我创建一个枚举E_编号,并实例化一个值为C将枚举与无效值进行比较,c,enums,comparison,C,Enums,Comparison,我想试着理解当我们比较枚举和无效值时编译器是如何工作的,以及程序在执行过程中做了什么 我在工作中发现了奇怪的源代码,不理解程序的行为,这并没有给我预期的结果 我写了下面的小程序来总结我的问题 我创建一个枚举E_编号,并实例化一个值为-1的变量a。 然后我对a执行比较,检查它是否属于枚举的范围 (我知道,这真的很奇怪,但这正是我在源代码中发现的!) 我希望结果告诉我不在范围内,因为第一个条件失败(a>=first\u ENUM)。 但是第二个条件(a 我的行为与gcc版本6.3.0 2017051
-1
的变量a
。
然后我对a
执行比较,检查它是否属于枚举的范围
(我知道,这真的很奇怪,但这正是我在源代码中发现的!)
我希望结果告诉我不在范围内,因为第一个条件失败(a>=first\u ENUM)
。
但是第二个条件(a
的失败给了我正确的结果(参见printf()
)
如果我在If
条件中的(int)
中投射a
,我会得到例外结果
那么在执行过程中会发生什么呢?程序是否考虑将-1
作为另一个可能的枚举值,该枚举值将定位在NB\u MAX\u NUMBER
之后?枚举上的
和gcc程序.c .\a.exe=第一个枚举)和&(a
=第一个枚举)?“TRUE”:“FALSE”); printf(“第二个条件=%s\n”,(a
不在范围内
第一个条件=真
第二个条件=假
我使用的是MINGW编译器(gcc(x86_64-win32-seh-rev1,由MINGW-W64项目构建)4.9.2)枚举器常量为。枚举数类型是一个未指定的整数类型,能够表示所有枚举数常量 : 每个枚举类型应与char兼容,char是一个有符号整数 类型,或无符号整数类型。类型的选择很简单 实现定义,128),但应能够表示 枚举的所有成员的值。枚举类型为 直到终止列表的}之后才结束 枚举器声明,然后完成 由于您没有枚举任何负值,因此该类型很可能是无符号类型。如果是,则
(E\u Number)某些整数将始终大于或等于零(0==FIRST\u ENUM
)
如果将enum
列表展开为:
typedef enum{
NUM_NOPE=-1,
NUM_1 = FIRST_ENUM,
NUM_2,
NUM_3,
NB_MAX_NUMBER
}E_Number;
<>你会强制编译器使用一个带签名的类型,结果会被逆转。 在编译程序中,编译器认为<代码> EyNo.<代码>为<代码>无符号int ,因为所有的合法值都是无符号的,所以-1被认为是~0U,即> = FixStEnEnm和 /P>
我的行为与gcc版本6.3.0 20170516(Raspbian 6.3.0-18+rpi1+deb9u1)相同
但是,如果我这样改变你的定义:
#include <stdio.h>
#define FIRST_ENUM -1
typedef enum{
NUM_1 = FIRST_ENUM,
NUM_2,
NUM_3,
NB_MAX_NUMBER
}E_Number;
int main()
{
E_Number a = -2;
if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
{
printf("In Range\n");
}
else
{
printf("Not in Range\n");
}
printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE");
printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE");
return 0;
}
引用自ISO/IEC 9899:1999,6.7.2.2p3 每个枚举类型应与char兼容,char是一个有符号整数 类型,或无符号整数类型。类型的选择很简单 实施定义,108),但应能够代表 枚举的所有成员的值
因此,当您声明枚举时,您无法事先确定C的实现将选择何种类型的数据来存储该变量。出于优化原因,如果在[-128,+127]之间存储枚举常量,编译器可能不会选择4字节的整数类型。实现可以选择char来存储枚举变量,但您不能确定。可以选择任何整数数据类型作为时间,因为它可以存储所有可能的值。有趣的是,我无法再现结果(MSVC),正如我所期望的,后两个分别为FALSE和TRUE。我不喜欢它的编写方式。如果需要一个“无效”的
enum
成员,它应该成为enum
的一部分。您确定此处显示的程序就是您编译和执行的程序吗?如何在If
条件“帮助”中的(int)
中“强制转换a
?那部分工作如你所料。显然给出错误结果的部分中没有if
。@eugene sh我理解你的评论!此代码存在于航空软件中,当函数“接收”枚举值时,它不确定结果是否有效,并且是否属于枚举值的范围。。。
pi@raspberrypi:~ $ ./a.out
Not in Range
1st condition = TRUE
2nd condition = FALSE
#include <stdio.h>
#define FIRST_ENUM -1
typedef enum{
NUM_1 = FIRST_ENUM,
NUM_2,
NUM_3,
NB_MAX_NUMBER
}E_Number;
int main()
{
E_Number a = -2;
if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
{
printf("In Range\n");
}
else
{
printf("Not in Range\n");
}
printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE");
printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE");
return 0;
}
pi@raspberrypi:~ $ ./a.out
Not in Range
1st condition = FALSE
2nd condition = TRUE