
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Abrahams
To the macro expansion mechanism, there are two main categories of preprocessing tokens--functional and non-functional.
Yeah I know, but I would never use those terms; too easily confused with function-like and object-like macros.
Yeah, maybe preprocessing tokens that have syntactic/semantic effect.
The functional preprocessing tokens are comma and the left and right parentheses. All others are non-functional (as input to macros). You have to be careful whenever you pass preprocessing tokens that are "functional" as arguments because they can have syntactic/semantic effect. Also note that an unmatched parenthesis can be considered pathological input. It is only possible to pass such a token by the use of a macro expansion, as in MACRO(LPAREN()). Unmatched parentheses in particular should *never* be passed to pp-lib primitives.
Even via LPAREN()? -- not that I'm going to reveal these details to people. I'm just telling them that unmatched parens can never be macro arguments.
LPAREN() can be used to create a left parentheses, and thus can be used to pass an unmatched left parentheses to a macro. That indirection is the only way to do that. However, it is inherently dangerous because the "argument-ness" of it cannot be preserved--it interferes: #define LPAREN() ( #define A(x) x #define B(x) A(x) A(LPAREN()) // okay, expands to: ( B(LPAREN()) // error: unmatched parenthesis However, you can pass the macro name LPAREN itself as as argument, provided it isn't later invoked in a context which would cause the above situation internally. There are valid reasons to programmatically create left and right parentheses. Regards, Paul Mensonides