How to expand macro and delete comma

倖福魔咒の 提交于 2020-01-23 02:04:20

问题


For example I want to write my own printf() alternative, but I have to perform calculations on the variable arguments:

#define log(fmt_string, ...) my_log(fmt_string, pack_args(__VA_ARGS__), __VA_ARGS__)

where pack_args(...) - is a macro too. How should I change this code to handle the only fmt_string presence scenario?

log("Some message here");

回答1:


In P99 I have two macros

#define P00_ARG(                                               \
 _1, _2, _3, _4, _5, _6, _7, _8,                               \
 _9, _10, _11, _12, _13, _14, _15, _16,                        \
  ... etc ...                                                  \
 _153, _154, _155, _156, _157, _158, _159,                     \
 ...) _159
#define P99_HAS_COMMA(...) P00_ARG(__VA_ARGS__,                \
 1, 1, 1, 1, 1, 1, 1,                                          \
 1, 1, 1, 1, 1, 1, 1, 1,                                       \
  ... etc ....                                                 \
 1, 1, 1, 1, 1, 1, 0, 0)

You can use this to determine if your argument has a comma (so there are more arguments than your format) or not (only a format). You can then use that to construct a call to one of two macros:

#define log(...) log2(P99_HAS_COMMA(__VA_ARGS__), __VA_ARGS__)
#define log2(N, ...) log3(N, __VA_ARGS__)
#define log3(N, ...) log ## N(__VA_ARGS__)

#define log0(FMT)              /* your version with format only goes here */
#define log1(FMT, __VA_ARGS__) /* your version with more goes here */



回答2:


How should I change this code to [handle] the only fmt_string presence scenario?

You cannot do this at all with a variadic macro in standard C. The standard explicitly specifies that in the invocation of a variadic macro "there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...)" (C2011, 6.10.3/4). You could allow the macro to be used with just one argument by changing it to ...

#define log(...) /* ... */

... but then you could not separate the format string from the other arguments -- at least not without re-introducing the same problem you have now.

You'll need to use a bona fide function if you need to support a zero-length variable argument list.



来源:https://stackoverflow.com/questions/32747785/how-to-expand-macro-and-delete-comma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!