
Edward Diener <eldiener <at> tropicsoft.com> writes:
I admit I do not understand how this can be. in the expansion to the code on that page it sure looks to me like 'HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))' will equate to 1 when __VA_ARGS__ = AMACRO since 'AMACRO (~)' = '()', '_TRIGGER_PARENTHESIS_ ()' = ',', and HAS_COMMA(,) = 1.
No your analysis is not correct. When the argument to HAS_COMMA is parsed, here, a substitution of the arguments of the surrounding macro replacement has already taken place. So as it is processed we have HAS_COMMA(_TRIGGER_PARENTHESIS_ AMACRO (~)) So now, when the arguments for HAS_COMMA are parsed _TRIGGER_PARENTHESIS_ is not followed by a '(' token, and so macro replacement for _TRIGGER_PARENTHESIS_ doesn't take place. Whatever the result of expanding the rest of the argument "AMACRO (~)" is _TRIGGER_PARENTHESIS_ *must* not be considered again. So the result of the argument expansion here is the token sequence '_TRIGGER_PARENTHESIS_' '(' ')' which then is passed to HAS_COMMA for substitution.
On 11/13/2011 9:48 PM, Gennadiy Rozental wrote:
On the other hand if you define it like this:
#define AMACRO(x,y) anything here
if fails to build.
In any case, as I said previous, this is corner case we should just document,
Yes, I see, this is certainly a corner case that doesn't work. When thinking of it now, with the argument above I found another one that doesn't work which is #define BMACRO() whatever because of the "(~)" in the tests. But that can simply be repaired by putting "()" there instead, I think. Jens