joe 发表于 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)

页: [1]
查看完整版本: ##和#在宏扩展中的作用