一个关于C语言宏替换的问题

简介:

在之前的一个项目中,通过macro来定义了一组位掩码:
#define FLAG_TYPE1 0x0001
#define FLAG_TYPE2 0x0002
#define FLAG_TYPE3 0x0004
#define FLAG_TYPE4 0x0008
...
#define TYPE(type) (FLAG_TYPE##type)
(这里对实例进行了简化,实例中将 TPYE 定义为 1<<(type-1) 并不妥当。)

由于使用这组位掩码的地方并不止一处,使用这个macro时传递的type参数并不是单纯的1、2、3、4,而是有着使用者自己的逻辑。
比如某使用者有如下定义:
#define COLOR_RED 1
#define COLOR_GREEN 2
#define COLOR_BLUE 3
如果写作 TYPE(1) 很不具可读性,写作 TYPE(COLOR_RED) 就好多了。

但是这时候发现,TYPE(COLOR_RED)在完成宏替换后变成了FLAG_TYPECOLOR_RED,并不是希望的FLAG_TYPE1。

怎么办呢?支持TYPE(COLOR_RED) => FLAG_TYPE1的宏替换能实现吗?

其实只要将TYPE这个宏换个写法就好了:
#define _TYPE(type) (FLAG_TYPE##type)
#define TYPE(type) _TYPE(type)

这样,TYPE(COLOR_RED)就能替换成FLAG_TYPE1。替换过程如下:
TYPE(COLOR_RED) => _TYPE(COLOR_RED) => _TYPE(1) => FLAG_TYPE1

为什么会这样呢?摘抄一段C标准:
After the arguments for the invocation of a function-like macro have been
identified, argument substitution takes place. A parameter in the replacement
list, unless preceded by a # or ## preprocessing token or followed by a ##
preprocessing token (see below), is replaced by the corresponding argument
after all macros contained therein have been expanded.

宏替换是从左到右被扫描,匹配到 ( 后,TYPE被展开,得到_TYPE;
_TYPE的参数COLOR_RED接着被展开了,因为COLOR_RED没有与 # 或 ## 相连接。而最开始的那种写法之所以不对,就是因为这一步COLOR_RED与 ## 相连,token被拼装了;
之后_TYPE再被展开,最终得到期待的FLAG_TYPE1。


目录
相关文章
|
7月前
|
C语言
【C语言】库宏offsetof(结构体成员偏移量计算宏)
【C语言】库宏offsetof(结构体成员偏移量计算宏)
54 0
|
7月前
|
程序员 C语言 UED
详解C语言assert宏
详解C语言assert宏
80 0
|
7月前
|
存储 编译器 Linux
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
|
4月前
|
编译器 程序员 C语言
C语言 宏
C语言 宏
42 5
|
7月前
|
编译器 C语言
C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)
C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)
|
5月前
|
Linux C语言
C语言宏IS_REACHABLE
C语言宏IS_REACHABLE
46 1
|
7月前
|
安全 编译器 程序员
C语言(16)----预处理中的宏以及预处理指令
C语言(16)----预处理中的宏以及预处理指令
60 2
|
6月前
|
安全 编译器 C语言
【C语言进阶篇】offsetof宏的介绍 及其实现
【C语言进阶篇】offsetof宏的介绍 及其实现
|
6月前
|
编译器 程序员 C语言
【C语言进阶篇】assert宏 使用详解
【C语言进阶篇】assert宏 使用详解
|
7月前
|
C语言
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)(下)
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)
42 0