[英]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.