简体   繁体   English

如何定义递归可变参数宏?

[英]How to define recursive variadic macros?

I am trying to convert boolean values, which represent bits of a signal bus, into an integer. 我正在尝试将表示信号总线位的布尔值转换为整数。 I am using the following construct: 我正在使用以下构造:

#define B_TO_UINT1(b00)      (((uint32_t) b00 << 0))
#define B_TO_UINT2(b01, ...) (((uint32_t) b01 << 1) | B_TO_UINT1(__VA_ARGS__))
#define B_TO_UINT3(b02, ...) (((uint32_t) b02 << 2) | B_TO_UINT2(__VA_ARGS__))
#define B_TO_UINT4(b03, ...) (((uint32_t) b03 << 3) | B_TO_UINT3(__VA_ARGS__))
// ...

When using the macro cascade to convert a 1-, 2- and 3-bit buses, the first 2 are OK, but the 3-bit conversion gives an error: 当使用宏级联转换1位,2位和3位总线时,前2位可以,但是3位转换会产生错误:

cmd = B_TO_UINT1(1);          // line_1
cmd = B_TO_UINT2(1, 0);       // line_2
cmd = B_TO_UINT3(0, 1, 1);    // line_3

Build errors on line_3 : line_3上生成错误:

warning C4003: not enough actual parameters for macro 'B_TO_UINT1'

error C2059: syntax error : '<<'

So, looks like the __VA_ARGS__ part is not expanding correctly with the recursion. 因此,似乎__VA_ARGS__部分未随递归正确扩展。 Is this really the case? 真的是这样吗? If so, is there a workaround? 如果是这样,是否有解决方法?

Apparently, MS VC++ behaves differently than expected with the recursive expansion of __VA_ARGS__ that includes multiple comma-separated arguments. 显然,MS VC ++的行为与__VA_ARGS__的递归扩展(包含多个逗号分隔的参数)不同。 When expanded in a nested macro, the the compiler treats the whole arg list as one argument. 在嵌套宏中扩展时,编译器会将整个arg列表视为一个参数。

Examples can also be seen here and here . 在这里这里也可以看到示例。

However, @Ise Wisteria suggested the EXPAND(x) macro as a workaround. 但是, @ Ise Wisteria建议使用EXPAND(x)宏作为解决方法。 Using this tip, I changed my code to: 使用此技巧,我将代码更改为:

#define EXPAND( x ) x
#define B_TO_UINT1(b00)      (((uint32_t) b00 << 0))
#define B_TO_UINT2(b01, ...) (((uint32_t) b01 << 1) | EXPAND( B_TO_UINT1(__VA_ARGS__)))
#define B_TO_UINT3(b02, ...) (((uint32_t) b02 << 2) | EXPAND( B_TO_UINT2(__VA_ARGS__)))
#define B_TO_UINT4(b03, ...) (((uint32_t) b03 << 3) | EXPAND( B_TO_UINT3(__VA_ARGS__)))
// ...

Now the build errors are eliminated. 现在,消除了构建错误。

Note: I am not explicitly saying "a bug", b/c there may be a place for understanding the standard the MS way, as described here . 注:我没有明确地说:“一个错误”,B / C有可能是理解标准MS方式的地方,如所描述这里

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

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