简体   繁体   English

C 宏 Arguments 包括逗号

[英]C Macro Arguments including comma

I would like to pass 2 arguments to a macro using another macro:我想使用另一个宏将 2 arguments 传递给一个宏:

#define A_AND_B     5,1
#define ADD(a, b)   a + b

int add_them(void)
{
    int result = ADD(A_AND_B);
    return result ;
}

I would hope that expands to我希望扩展到

int result = 5 + 1;

and I get 6. Instead I get我得到 6. 相反我得到

Error       'ADD' undeclared (first use in this function)   
Error       macro "ADD" requires 2 arguments, but only 1 given  

Is there a way around this?有没有解决的办法?

As is often the case, you need an extra level of (macro) indirection:通常情况下,您需要额外的(宏)间接级别:

#define A_AND_B     5,1
#define ADD(...)    ADD_(__VA_ARGS__)
#define ADD_(a, b)   a + b

int add_them(void)
{
    int result = ADD(A_AND_B);
    return result ;
}

ADD is defined as variadic so that it will work as either ADD(A_AND_B) or ADD(A, B) . ADD被定义为可变参数,因此它将作为ADD(A_AND_B)ADD(A, B)工作。

This works because __VA_ARGS__ in the replacement body of ADD is replaced with the actual arguments before the replacement body is scanned for macros.这是有效的,因为在扫描替换体中的宏之前, ADD替换体中的__VA_ARGS__被替换为实际的 arguments。

Per C 2018 6.10.3.1, a compiler first identifies the arguments for a function-like macro and then performs macro replacement on the arguments, followed by macro replacement for the function-like macro.根据 C 2018 6.10.3.1,编译器首先将 arguments 识别为类函数宏,然后对 arguments 执行宏替换,然后对类函数宏进行宏替换。 This means that, in ADD(A_AND_B) , the argument is identified as A_AND_B before it is replaced with 5,1 .这意味着,在ADD(A_AND_B)中,参数在被替换为5,1之前被标识为A_AND_B As the macro invocation has only this single argument and the macro is defined to have two parameters, an error is diagnosed.由于宏调用只有一个参数,而宏被定义为有两个参数,因此诊断出错误。

Given your definition of ADD , there is no way to change this behavior in a compiler that conforms to the C standard.鉴于您对ADD的定义,无法在符合 C 标准的编译器中更改此行为。

You can instead use another macro to expand the arguments and apply the desired macro:您可以改用另一个宏来扩展 arguments 并应用所需的宏:

#define Apply(Macro, Arguments) Macro(Arguments)

then int result = Apply(ADD, A_AND_B);然后int result = Apply(ADD, A_AND_B); will work.将工作。 That will identify ADD and A_AND_B as arguments to Apply .这会将ADDA_AND_B识别为 arguments 以Apply Then it will expand those, producing an unchanged ADD and 5,1 .然后它将扩展那些,产生不变的ADD5,1 Then the macro replacement for Apply produces ADD(5,1) .然后Apply的宏替换生成ADD(5,1) Then this is again processed for macro replacement, which replaces ADD(5,1) in the ordinary way.然后再次处理宏替换,以普通方式替换ADD(5,1)

Note that good practice is usually to define ADD as #define ADD(a, b) ((a) + (b)) to avoid unexpected interactions with other operators neighboring the use of the macro.请注意,好的做法通常是将ADD定义为#define ADD(a, b) ((a) + (b))以避免与使用该宏的其他运算符发生意外交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM