- 主题:[求助]求助:__VA_ARGS__ 在std11下的问题
当__VA_ARGS__为空时,总是算不对,请大家帮忙想想有什么办法
--
修改:haman2013 FROM 120.245.92.*
FROM 120.245.92.*

-E Stop after the preprocessing stage; do not run the compiler proper.
The output is in the form of preprocessed source code, which is
sent to the standard output.
在终端 gcc -E your_source.c 检查宏展开后代码是否正确
【 在 haman2013 的大作中提到: 】
: 当__VA_ARGS__为空时,总是算不对,请大家帮忙想想有什么办法
--
FROM 120.239.197.*
这是因为按照 C 语言标准(C99以上),空的宏参数不会被省略,所以
#define ARGS_NUM(...) ARGS_COUNT(placeholder, ## __VA_ARGS__, 4, 3, 2, 1, 0)
在没有给定参数时,会展开为
ARGS_COUNT(placeholder, , 4, 3, 2, 1, 0)
正是为了解决这一问题,GNU CPP 才特别引入了 “## __VA_ARGS__” 这种语法。它会在 __VA_ARGS__ 为空时省略前一个逗号,详见
https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html
因此,使用 GNU 扩展以后,ARGS_NUM 在没有参数时会展开为
ARGS_COUNT(placeholder, 4, 3, 2, 1, 0)
比标准 C 少一个逗号,也就少一个参数。
当你指定了 c11 标准以后,GNU 扩展被关闭,主楼代码就会因为多出的逗号而出现编译错误。
C 标准没有提供解决这一问题的办法,但是这个 SO 贴子的回复里提供了一些解决方案:
https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
【 在 haman2013 的大作中提到: 】
: 当__VA_ARGS__为空时,总是算不对,请大家帮忙想想有什么办法
:
:
--
FROM 171.43.221.*
谢谢Lele
那个帖子看过,应该是都是通过##来吃掉前面的“,”
感觉上通过变换应该是可以把0个参数和1个参数分开,但是还没有找到办法。
特别前面还有a,b, c, d几个固定参数就更麻烦。
【 在 lele 的大作中提到: 】
: 这是因为按照 C 语言标准(C99以上),空的宏参数不会被省略,所以
: #define ARGS_NUM(...) ARGS_COUNT(placeholder, ## __VA_ARGS__, 4, 3, 2, 1, 0)
: 在没有给定参数时,会展开为
: ...................
--
FROM 120.245.92.*
参考boost pp,关于宏的奇技淫巧,它应该都趟完坑了。
比如BOOST_PP_VARIADIC_SIZE之类的
不过它有些特性是C++的模板推导实现的,不是纯宏。
--
修改:z16166 FROM 114.241.225.*
FROM 114.241.225.*
以下这个可行,谢谢几位
#define EMP(...)
#define CX(x,...) COMMA x ()
#define COMMA() ,
#define SWAP(...) SWAPX(__VA_ARGS__)
#define SWAPX(x, y,...) y()
#define ARGS_COUNT(_1, _2, _3, _4, _5, _6, ...) _6
#define ARGS_COUNTX(...) ARGS_COUNT(__VA_ARGS__)
#define ARGS_NUM(...) ARGS_COUNTX(ph SWAP(CX(__VA_ARGS__) EMP, COMMA) __VA_ARGS__, 4, 3, 2, 1, 0)
--
FROM 120.245.92.*