Boost logo

Boost :

Subject: Re: [boost] [preprocessor] [variadic] BOOST_PP_VARIADICS vs BOOST_NO_VARIADIC_MACROS
From: Edward Diener (eldiener_at_[hidden])
Date: 2012-01-14 09:52:11


On 1/14/2012 9:07 AM, lcaminiti wrote:
>
> Edward Diener-3 wrote
>>
>> On 1/14/2012 5:42 AM, Lorenzo Caminiti wrote:
>>> On Sun, Dec 18, 2011 at 10:18 AM, Paul Mensonides<pmenso57@>
>>> wrote:
>>>> On Sat, 17 Dec 2011 12:45:26 -0800, lcaminiti wrote:
>>>>> Why does Boost.Preprocessor redefines BOOST_PP_VARIAIDCS instead of
>>>>> just
>>>>> using BOOST_NO_VARIADIC_MACROS from Boost.Config?
>>>>
>>>> The pp-lib requires more than just superficial variadic macro support.
>>>> I.e. BOOST_PP_VARIADICS macro is stronger.
>>>>
>>>>> Furthermore, GCC supports variadics also when C++11 extensions are not
>>>>> enabled so I think the following should not&&
>>>>> __GXX_EXPERIMENTAL_CXX0X__:
>>>>>
>>>>> // File: boost/preprocessor/config/config.hpp # /* Wave (C/C++), GCC
>>>>> (C++) */
>>>>> # elif defined __WAVE__&& __WAVE_HAS_VARIADICS__ || defined
>>>>> __GNUC__
>>>>> && __GXX_EXPERIMENTAL_CXX0X__
>>>>> # define BOOST_PP_VARIADICS 1
>>>>
>>>> Because it isn't standard C++98. It can be enabled via a command line
>>>> definition of BOOST_PP_VARIADICS. It is enabled by default (on GCC)
>>>> when
>>>> in C++11 mode. I believe that GCC 4.7 actually finally defines
>>>> __cplusplus
>>>> correctly as well.
>>>
>>> It is annoying to manually -DBOOST_PP_VARIADICS. That is especially
>>> true for libraries like Boost.ScopeExit and Boost.Closure that use
>>> variadics in their public APIs so the end user is required to manually
>>> define BOOST_PP_VARIADICS when Boost.Preprocessor does not
>>> automatically detect it... (e.g., on GCC 4.5.3 without -std=c++0x).
>>
>> You can just add:
>>
>> #define BOOST_PP_VARIADICS
>>
>> in your header files before using Boost PP headers. That isn't really
>> that annoying to do if you want to force it.
>>
>
> Yes, in scope_exit.hpp, I could do:
>
> #include<config.hpp>
> #ifndef BOOST_NO_VARIADIC_MACROS
> #define BOOST_PP_NO_VARIADICS
> #endif
> #include<boost/preprocessor/variadic/size.hpp>
> ...
>
> But that way ScopeExit will make BOOST_PP_VARIADICS equivalent to
> BOOST_NO_VARIADIC_MACROS... that seems bad practice... then why having two
> macros in the first place?

This was Paul's decision. My original plan was to use
BOOS_NO_VARIADIC_MACROS but he was pretty adamant that he did not want
any warnings from Boost PP and he wanted C99/C++0x-like support for
variadic macros, so he made it more restrictive for Boost PP.

>
> The story is different if the forced definition of BOOST_PP_VARIADICS is
> left to the end user- the user is hen on his own in overriding the default
> detection of the Boost.Preprocessor configuration. However, that adds extra
> configuration effort on the user side so Boost.Preprocessor should be as
> accurate as possible in defining BOOST_PP_VARIADICS on all compilers that
> actually support Boost.Preprocessor variadics.
>
>
>
>>>
>>> Can we define what "extra" features are required by BOOST_PP_VARIADICS
>>> so I can write tests and run them to the Boost compilers and then
>>> refine the definition of BOOST_PP_VARIADICS to automatically detect
>>> all compilers where Boost.Preprocessor variadic support work.
>>
>> Look at preprocessor/config/config.h for the internal logic for defining
>> BOOST_PP_VARIADICS.
>>
>
> Yes, I found that logic (see below). But I was asking for exactly why this
> logic needs to be more conservative than BOOST_NO_VARIADIC_MACROS? In other
> words, what are the actual pp features that are required to define
> BOOST_PP_VARIADICS but not to define BOOST_NO_VARIADIC_MACROS.

You will have to argue with Paul.

>
> GCC 4.5.x without -std=c++0x is a good example. Why is BOOST_PP_VARIADICS
> not automatically defined for this compiler? What are the specific issuers?
> I was able to use at least VARIADIC_SIZE and VARIADIC_TO_SEQ on that
> compiler without any issue at all...
>
> # /* BOOST_PP_VARIADICS */
> #
> # if !defined BOOST_PP_VARIADICS
> # /* variadic support explicitly disabled for all untested compilers */
> # if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ ||
> defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined
> __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined
> __HP_aCC&& !defined __EDG__ || defined __MRC__ || defined __SC__ || defined
> __IBMCPP__ || defined __PGI
> # define BOOST_PP_VARIADICS 0
> # /* VC++ (C/C++) */
> # elif defined _MSC_VER&& _MSC_VER>= 1400&& !defined __EDG__
> # if _MSC_VER>= 1400
> # define BOOST_PP_VARIADICS 1
> # define BOOST_PP_VARIADICS_MSVC 1
> # else
> # define BOOST_PP_VARIADICS 0
> # endif
> # /* Wave (C/C++), GCC (C++) */
> # elif defined __WAVE__&& __WAVE_HAS_VARIADICS__ || defined __GNUC__&&
> __GXX_EXPERIMENTAL_CXX0X__
> # define BOOST_PP_VARIADICS 1
> # /* EDG-based (C/C++), GCC (C), and unknown (C/C++) */
> # elif !defined __cplusplus&& __STDC_VERSION__>= 199901L || __cplusplus
>> = 201103L
> # define BOOST_PP_VARIADICS 1
> # else
> # define BOOST_PP_VARIADICS 0
> # endif
> # elif !BOOST_PP_VARIADICS + 1< 2
> # undef BOOST_PP_VARIADICS
> # define BOOST_PP_VARIADICS 1
> # if defined _MSC_VER&& _MSC_VER>= 1400&& !(defined __EDG__ || defined
> __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined
> __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined
> __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined
> __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ ||
> defined __PGI)
> # define BOOST_PP_VARIADICS_MSVC 1
> # endif
> # else
> # undef BOOST_PP_VARIADICS
> # define BOOST_PP_VARIADICS 0
> # endif
>
> Edward, thanks again for providing the variadic support which I found very
> useful in all my libraries.

You are very welcome. It was a labor of love, especially when one has to
deal with VC++ and its preprocessor headaches, also in my extra VMD
functionality.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk