C语言的预编译是先于enum,什么意思呢,看代码:
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
enum
{
ENUM_ABC,
ENUM_DEF,
};
#define DEF ENUM_DEF
int main(int argc, char **argv)
{
#if DEF == ENUM_ABC
printf("ENUM_ABC\r\n");
#elif DEF == ENUM_DEF
printf("ENUM_DEF\r\n");
#endif
return 0;
}
一开始觉得运行结果应该是“ENUM_DEF”,但是实际上是:
这种低级问题我还想了很久才想起来,C语言在预编译的时候,预编译器只是展开#include、#define等命令,处理条件编译#if、#else等命令,删除注释,添加行号和文件标识等操作,所以这个时候枚举类型是“未生效”的,枚举类型数据的“展开”是在编译阶段由编译器进行的,因此这里 “#if DEF == ENUM_ABC” 在预编译的时候就会有问题,按道理预编译器会报 ENUM_ABC 和 ENUM_DEF 未定义的警告或者错误(根据gcc的-Wundef -Eundef标志),如果没有设置成报错,那么编译器会把未定义的这个宏设置成0(evaluates to 0),因此这句话 “#if DEF == ENUM_ABC” 的展开流程为:
DEF ==>> ENUM_DEF
ENUM_DEF ==>> 0
ENUM_ABC ==>> 0
那么 #if DEF == ENUM_ABC 就是 #if 0 == 0,因此永远在第一条就成立,所以输出的就是 “ENUM_ABC”。
想要控制编译流程的话,还是要用 #define 的方式来控制:
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#define ENUM_ABC 0
#define ENUM_DEF 1
#define DEF ENUM_DEF
int main(int argc, char **argv)
{
#if DEF == ENUM_ABC
printf("ENUM_ABC\r\n");
#elif DEF == ENUM_DEF
printf("ENUM_DEF\r\n");
#endif
return 0;
}
这样输出就正确了。