请选择 进入手机版 | 继续访问电脑版

risc-v中文社区

 找回密码
 立即注册
查看: 1203|回复: 0

[原创] ##和#在宏扩展中的作用

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-9-23 16:08:04 | 显示全部楼层 |阅读模式
#define PRINT(ARG) printf(#ARG)
那么:PRINT(Hello word Any one 1);将会扩展为printf("Hello word Any one 1");
也就是说#ARG的作用就是将ARG的内容作为一个整体,然后再加上双引号,在语法上就是一个C字符串。
#define CAT(AA,BB) AA##BB
#define POWERMATH(AA,BB) AA##e##BB
那么 int n = CAT(10,11);扩展为int n=1011;
int n2 = POWERMATH(2,3);扩展为int n2=2e3;即n2=2000;
#define __define_initcall(fn,id) \
        static const initcall_t __initcall_##fn##id \
        __attribute__((__used__,__section__("initcall"#id"init")) = fn;
那么__define_initcall(funname,1);或__define_initcall(funname,1s);将会被扩展为:
static const initcall_t类型的变量,变量名为 __initcall_funname1或__initcall_funname1s,
关键是这个变量连接之后将放在initcall1init或initcall1sinit节中,同时,不管这个变量有没有用到,
GCC都会在连接后的二进制文件中保留它,不会被优化掉。
也就是说##的作用就是将两个宏变量拼接在一起作为一个新的标识符

#define ARG1 10
#define ARG2 12
#define CAT(AA,BB) AA##BB
那么:int n = CAT(ARG1,ARG2);将会出错,即CAT(ARG1,ARG2)扩展为ARG1ARG2,不会再将ARG1和ARG2展开为10和12,也就是说ARG1ARG2是未被定义的符号,编译出错。也可以看出来,CAT(ARG1,ARG2)在扩展之前不会先将ARG1,ARG2替换为10,12。但是,如果我们想将ARG1,ARG2最终替换为10,12那要怎么做呢?
可以加一个中间宏:
#define _CAT(AA,BB) AA##BB
#define CAT(AA,BB) _CAT(AA,BB)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-3-28 18:02 , Processed in 0.013818 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表