If you want to incorporate an unmatched opening parenthesis in a replacement list, you need to add a layer of indirection:
#define LPAREN (
#define PREPEND_AND_APPLY_STRANGE(x) STRANGE_MACRO LPAREN x,STRIP_PAREN
This way the parenthesis won't be considered part of an invocation until the correct syntax is complete.
Unfortunately there's a limitation to this technique: by the time the call to STRANGE_MACRO
is fully constructed, it's past the point where it would be eligible for rescanning - since the start and end of the expression were built across two different calls that took place at the same level, the whole thing never appeared in one rescan list - and will never actually expand; you'll just get STRANGE_MACRO ( x,y,z,w)
dumped in your output. You need to force a rescan at the top level:
#define EXPAND(...) __VA_ARGS__
The macro does nothing, but does mean its argument gets to be put in a rescan list as a complete unit and will thus finally expand. So the closest you can get to your desired syntax would be this:
EXPAND(
MACRO1(identifier) (
....
)
MACRO1(identifier) (
....
)
)
...so you don't need to disfigure each of your custom blocks with its own EXPAND
, but you do need to wrap the whole program in one. And no you can't hide the wrapper by putting an #include
directive within EXPAND
, as directives can't appear within invocations. (Still, perhaps you can make something useful of it by reinventing namespace
or something similar that your syntax might need.)
This also has the disadvantage that the C compiler will perceive your entire program as being on one line, which will hurt error reporting somewhat - although you were already halfway to this problem, as each declaration block would also have seemed to be on only one line had the original version worked.