使用C中的枚举来实现类型安全是有问题的,因为它们基本上只是整数.实际上,枚举常量被定义为int标准的类型.
为了实现一点类型的安全性我用这样的指针做了一些技巧:
typedef enum
{
BLUE,
RED
} color_t;
void color_assign (color_t* var, color_t val)
{
*var = val;
}
Run Code Online (Sandbox Code Playgroud)
因为指针具有比值更严格的类型规则,所以这会阻止这样的代码:
int x;
color_assign(&x, BLUE); // compiler error
Run Code Online (Sandbox Code Playgroud)
但它不会阻止这样的代码:
color_t color;
color_assign(&color, 123); // garbage value
Run Code Online (Sandbox Code Playgroud)
这是因为枚举常量基本上只是一个int,可以隐式赋值给枚举变量.
有没有办法编写这样的函数或宏color_assign,即使对于枚举常量也可以实现完整的类型安全性?
说,我们有
enum E
{
Foo = 0,
Bar = 1
};
Run Code Online (Sandbox Code Playgroud)
现在,我们做到了
enum E v = ( enum E ) 2;
Run Code Online (Sandbox Code Playgroud)
然后
switch ( v )
{
case Foo:
doFoo();
break;
case Bar:
doBar();
break;
default:
// Is the compiler required to honor this?
doOther();
break;
}
Run Code Online (Sandbox Code Playgroud)
由于上面的开关处理枚举的每个可能列出的值,是否允许编译器优化掉default上面的分支,或者在enum的值不在列表中的情况下具有未指定或未定义的行为?
正如我期望C和C++的行为应该类似,问题在于两种语言.但是,如果在这种情况下C和C++之间存在差异,那么了解它也会很好.
所以enum的工作原理如下:
enum {
false,
true
}
Run Code Online (Sandbox Code Playgroud)
这相当于
int false = 0
int true = 1
Run Code Online (Sandbox Code Playgroud)
我为什么不可以替代enum用#define?
#define FALSE 0
#define TRUE 1
Run Code Online (Sandbox Code Playgroud)
对我来说,它们似乎是可以互换的.我知道#define能够处理参数,因此以完全不同的方式运行enum.enum我们#define 在这种情况下的主要用途究竟是什么?
如果我猜测,因为它#define是一个预处理器功能,enum将具有一些运行时优势.我有多远?
提前致谢.
我从教科书中了解到,枚举的典型定义如下:
enum weather {
sunny,
windy,
cloudy,
rain,
} weather_outside;
Run Code Online (Sandbox Code Playgroud)
然后声明一个 var,如下所示:
enum weather weather_outside = rain;
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果可以通过说eg来使用枚举常量rain,它保持整数3,那么具有类似类型的更复杂的减速等于3的确切用途和意义是什么enum weather weather_outside = rain;(weather_outside因为枚举值只能是编译时常量)?为什么不直接使用 aconst或 宏呢?我有点困惑枚举是否真的有必要?!