Boost logo

Boost :

Subject: Re: [boost] Alternative implementation for BOOST_PP_VARIADIC_SIZE
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2011-11-14 23:35:33

On Mon, 14 Nov 2011 19:57:31 +0000, Jens Gustedt wrote:

> I think any macros that are designated to be used by an "end user" must
> mediate between those different views and provide an end result that
> reads well for that end user, who I think expects syntax written as if
> it where core language.
> In P99 I use the IS_EMPTY macro for exactly that, try to accommodate
> that supposed expectation.

I strongly disagree that catering to that expectation is a good thing in
any context. The sooner people realize (and expect) that the preprocessor
behaves differently than the core language, the better. Virtually all
issues related to the misuse of the preprocessor stems from attempting to
make object-like macros look like constant variables and function-like
macro invocations look like underlying-language function calls. At best,
the correlation between function-like macro invocations and function calls
should be incidental. It should never be considered to be a goal. That
is a fundamentally broken mentality.

Preprocessing directives and macro invocations are part of an EL (DSEL
without the DS) that overlays the underlying language; they are not part
of the syntax or semantics of the underlying language. The preprocessing
phases of translation are best thought of as a executing a program
overlaid on the source that translates that source into a token sequence
presented to the C or C++ parser. Anything else is just perpetuating the

While it is not my business to force anyone to do anything, I am certainly
not going to write code which may be viewed as best practice that
intentionally perpetuates that mentality. And this really is about that
mentality. It isn't about the slight syntactic inconvenience. Sure, with
a sequence (a)(b)(c), that's a lot of extra parentheses (and you get other
benefits with sequences such as elements containing commas and data
structures with unbounded length), but a tuple (a,b,c) does not have a lot
of extra parentheses. You'd get MACRO() vs. MACRO((a,b,c)) which has an
incidental two extra parentheses and the two invocation cases are
unambiguously, compiler-error-free detectable as different. The only
supposed "downside" is that it doesn't look like a regular function call
which is a symptom of the above mentality and is not actually a downside
(it might even be an upside given the status quo which has been around
since the early days of C).

With an interface macro without a certain domain (where the necessary
domain restrictions are reasonable), it really depends on the reuseability
level of the interface. Otherwise, there are serious repercussions
related to recursion inherent in any forwarding interface (i.e. convert-
and-forward) unless you do something with recursion like Chaos does which
requires an extremely good preprocessor.

In the typical case, it is never a good idea, even at the interface
level. In some more advanced cases, it isn't that big a deal. For
example, in Lorenzo's (sp?) contract programming library, the syntax is so
blatantly not that of the underlying language and the domain is specific
enough that he can get away with it without it being particularly
adverse. In that case, the resulting syntax is blatantly a DSEL and
therefore can have whatever syntax it wants since confusion between
different "languages" is nearly impossible. That scenario, however, is
quite a bit different than some macro just defined as A(a, b, ...) as
opposed to A((a, b, ...)) or A((a)(b)(c)) just to make it look like a
function call.

Paul Mensonides

Boost list run by bdawes at, gregod at, cpdaniel at, john at