My actual code example is quite complex, but I will try to summarize the behavior I am seeing with a simple illustration.
I have a macro that I want to be able to call individually, or multiple times as a part of a larger macro expansion:
#define DO_STUFF(name,...) \
STUFF1(name,__VA_ARGS__) \
STUFF2(name,__VA_ARGS__) \
STUFF3(name,__VA_ARGS__)
I can use DO_STUFF(dave, int, char)
and similar variations directly in a source file and it generates the code I expect.
I also want to invoke big lists of the DO_STUFF
macro with another list of inputs. In order to handle this case, I am using boost preprocessor with a sequence of tuples (or variadic sequence):
DO_LOTS_OF_STUFF(
(dave, ball, pen) \
(alice, cat, dog, bicycle) \
(peter, bird) )
My definition of DO_LOTS_OF_STUFF
looks like:
#define DO_LOTS_OF_STUFF(SEQ) \
BOOST_PP_SEQ_FOR_EACH( \
INVOKE_DS, _, \
BOOST_PP_VARIADIC_SEQ_TO_SEQ(SEQ) \
)
#define INVOKE_DS( r, data, elem ) \
DO_STUFF(BOOST_PP_TUPLE_ENUM(elem)); \
When I invoke DO_LOTS_OF_STUFF
as illustrated above, STUFF1
, STUFF2
, and STUFF3
are all invoked with an extra comma at the end with an empty parameter.
If I break the expansion at the point that DO_STUFF
is invoked (by changing its name), the preprocessor output looks like I expect:
DO_STUFF(dave, ball, pen)
DO_STUFF(alice, cat, dog, bicycle)
DO_STUFF(peter, bird)
If I break the expansion at the STUFF1
, STUFF2
, and STUFF3
level, they appear in the output with an extra empty parameter:
STUFF1(dave, ball, pen,)
STUFF2(dave, ball, pen,)
STUFF3(dave, ball, pen,)
STUFF1(alice, cat, dog, bicycle,)
STUFF2(alice, cat, dog, bicycle,)
STUFF3(alice, cat, dog, bicycle,)
STUFF1(peter, bird,)
STUFF2(peter, bird,)
STUFF3(peter, bird,)
Is this just one of those things to avoid in preprocessor meta-programming like "don't use ##
"? "Don't use __VA_ARGS__
in nested macros"?
Any advice on how to define DO_STUFF
or DO_LOTS_OF_STUFF
to avoid this issue?