如何让一个宏扩展为另一个宏的 arg 名称

How to have a macro expand into the arg name of another macro

提问人:Abdulmalek Almkainzi 提问时间:10/5/2023 更新时间:10/6/2023 访问量:61

问:

例如:

#define Y (b * 2)
#define X(b) Y

int main()
{
    printf("%d", X(4)); // Want it to print 8, but doesn't work
}

使用 C 宏可以做到这一点吗?

C-预处理器

评论

1赞 Gerhardh 10/5/2023
还必须将变量传递给第二个宏。像 macro 这样的函数不会创建一个新作用域,其中具有名称或参数的变量是已知的。 仅在定义宏的行中已知。无处。=> 和b#define Y(_b) ((_b) * 2)#define X(b) Y(b)
0赞 KamilCuk 10/5/2023
我不明白为什么不呢?#define Y(b) (b * 2)#define X(b) Y(b)

答:

1赞 Lundin 10/5/2023 #1

如注释中所述,宏参数名称具有特定函数类宏的局部范围,因此无法从宏外部访问它。

不过,在称为“X 宏”的设计模式中也可以实现类似的情况。它基于在宏中提供数据列表(或单个项目),而不是让该列表宏采用不同的宏作为参数,以便将某些内容应用于数据列表。

例:

#include <stdio.h>

// here X will be an external function-like macro with 1 parameter:
#define LIST(X) \
  X(4)          \
  X(8)

// some macros with 1 parameter that should print and possibly also multiplicate
#define PRINTx1(a) printf("%d ", (a));  // note the semicolon here
#define PRINTx2(a) printf("%d ", (a)*2);

int main (void)
{
  LIST(PRINTx1)  // note the lack of semicolon here
  puts("");
  LIST(PRINTx2)
}

输出:

4 8 
8 16 

以上所有内容将像这样展开:

PRINTx1(4) PRINTx1(8)
puts("");
PRINTx2(4) PRINTx2(8)

->

printf("%d ", (4)); printf("%d ", (8));
puts("");
printf("%d ", (4)*2); printf("%d ", (8)*2);