繁体   English   中英

C 预处理器宏多个 arguments

[英]C preprocessor macro multiple arguments

所以我有这个“检查”宏,它需要两个 arguments:

#define check(reg, n) ((reg >> n) & 1U)

我有这个参数列表:

#define TEST_ARGS 10, 1

编码:

check(TEST_ARGS);

预期扩展:

((10 >> 1) & 1U)

实际扩展:

((10, 1 >> ) & 1U)

如何为“检查”宏定义多个 arguments 以获得预期结果?

非常感谢。

在顶级(非宏替换)输入中,宏调用参数列表在 arguments 被宏扩展之前立即解析。 (一定是这种情况,因为与###宏运算符一起使用的宏 arguments 没有扩展,并且在检查替换体之前不知道。)

但是,在替换正文中扫描宏之前,替换正文中的参数将替换为相应的 arguments(如果该参数未与###一起使用,则会进行宏扩展)。

所以你可以通过添加一个间接级别来达到你想要的效果。 但是,您可能希望使用 varargs 宏,以防调用者使用显式逗号:

#define CHECK(...) CHECK_(__VA_ARGS__)
#define CHECK_(reg, n) ((reg >> n) & 1U)

#define TEST_ARGS 10, 1
CHECK(TEST_ARGS)

测试:

$ $ gcc -x c -E - <<<'#define CHECK(...) CHECK_(__VA_ARGS__)
> #define CHECK_(reg, n) ((reg >> n) & 1U)
> 
> #define TEST_ARGS 10, 1
> CHECK(TEST_ARGS)'
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "<stdin>"




((10 >> 1) & 1U)

预处理器进行文本替换(实际上它替换了标记)。 因此,如果

#define check(reg, n) ((reg >> n) & 1U)
#define TEST_ARGS 10, 1

然后

check(TEST_ARGS);

被预处理为:

check(10, 1,);  

其中第一个参数是完整的标记10,1 ,第二个是空的

简而言之,这个问题与TEST_ARGS被视为check()宏的第一个参数有关,并且不知何故,一个空参数被认为是编译器的第二个参数。 (在我尝试的所有编译器上,如果缺少第二个参数,编译器将生成错误)。


您需要一定程度的间接性以允许宏TEST_ARGS在传递给check()之前进行扩展。

例如:

#define check2(...) check(__VA_ARGS__)

然后,使用check2(TEST_ARGS)


对于 MSVC,我必须做一些更复杂的事情:

#define V_(...) __VA_ARGS__
#define I_(M,...) V_(M(__VA_ARGS__))
#define check2(...) I_(check, __VA_ARGS__)

暂无
暂无

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

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