【C语言】预编译先于enum

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等命令,删除注释,添加行号和文件标识等操作(参考C语言编译过程:https://blog.csdn.net/tq384998430/article/details/53289648),所以这个时候枚举类型是“未生效”的,枚举类型数据的“展开”是在编译阶段由编译器进行的,因此这里 “#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;
}

这样输出就正确了。

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值