Subject: Re: [boost] Alternative implementation for BOOST_PP_VARIADIC_SIZE
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-14 06:26:43
On Mon, Nov 14, 2011 at 6:14 AM, Gennadiy Rozental <rogeeff_at_[hidden]> wrote:
> Paul Mensonides <pmenso57 <at> comcast.net> writes:
>> On Sun, 13 Nov 2011 21:10:11 -0800, Jeffrey Lee Hellrung, Jr. wrote:
>> > I'm just curious, is
>> > --------
>> > #define A(...)
>> > A(,)
>> > --------
>> > legal?
>> Yes. "Empty" is a valid argument in >= C99 and >= C++0x. An example of
>> when an empty argument actually appears when passing around a cv-
>> qualifier: nothing | const | volatile | const volatile. This is only one
>> of many many scenarios where emptiness is a valid element and has meaning.
> Yes. This all is "legal" and "valid", but does it have meaning? I doubt it.
> Show me sane example where one would develop macro FOO which takes two arguments
> and tell users to invoke it like this FOO(,) or FOO(a,) or FOO(a,b). Instead one
> can present a macro which takes variadic data and does different things
> depending on how many arguments passed (0, 1, or 2). So the invocations would
> look like FOO(), FOO(a), FOO(a,b) - much better IMO.
IMO, the point is that there is nothing wrong with you providing
FOO(a, b) to your end users so as part of your public API and document
that it should never be called as FOO(,). Then you internally convert
the variadic `a, b` to the sequence (a)(b) and do your pp
manipulations internally using pp-sequences. This way the
Boost.Preprocessor library that you use to implement your internals
supports a sound and scalable pp data structure (sequence) and your
users benefit from using the variadic syntax that is more natural to
them-- everyone wins :). My Boost.Local and Boost.Contract libraries
follow this exact same pattern.
> FOO(,) is a stone in a road to awk-like hell and should be strictly forbidden
> from the end user code. It might only be used in some corner cases deep in
> library code and never exposed.
> So, all the theoretical corner cases aside FOO() should be invocation with zero
> arguments and FOO(a) with one.
I disagree, this is not theoretical. If you write a general purpose
library like Boost.Preprocessor you need to make sure it is general
(not theoretical) in that it handles all the uses cases that can arise
within what the C++ standard specifies (including corner use cases).
Otherwise, as the Boost.Preprocessor author you will be making
assumptions like "my users will _never_ have to use a macro FOO(,)"
which might be true in most but no all cases.