Boost logo

Boost :

Subject: Re: [boost] [config] Rethinking feature macros?
From: paul (pfultz2_at_[hidden])
Date: 2017-11-06 16:05:18


On Mon, 2017-11-06 at 03:15 +0200, Peter Dimov via Boost wrote:
> Now that there are standard feature-testing macros 
> (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0096r5.html) that 
> are being implemented by at least g++ and clang++, would it perhaps make 
> sense for us to reevaluate our decision to provide negative macros in 
> Boost.Config and start defining the standard feature macros instead on the 
> compilers that don't support them?

I think it would be better to provide macros like how the Fit library does:

https://github.com/pfultz2/Fit/blob/master/include/fit/config.hpp#L93

The macros are always defined, but can be easily overridden. So if a compiler has a bug with the feature or is lying, then the user can easily build by adding `-DBOOST_HAS_FEATURE=...` to compilation to enable or disable the feature in boost. 

The current setup this is not possible because we always write `#ifdef BOOST_NO_FEATURE` and there is no way to express that the macro should be left undefined even if Boost.Config thinks it should be defined. Instead we should be writing `#if !BOOST_HAS_FEATURE` and Boost.Config defines it 0 or 1 if it hasn't already been defined by the user.

>
> This would seem to require less maintenance, and the feature macro can be 
> used without waiting for Boost.Config to add it.
>
> For a concrete example, let's take noexcept in function types. This is 
> __cpp_noexcept_function_type, and is implemented by g++ 7, clang 4, clang 5 
> (in C++17 mode), and apparently in the latest VS2017 preview.
>
> noexcept function pointers break Boost.Bind, and to fix it, I need to add 
> overloads for them, but only if they are implemented, otherwise the 
> overloads would be an error.
>
> With the feature macro, I can just #ifdef __cpp_noexcept_function_type and 
> it will immediately work on g++ and clang++ and all compilers that don't 
> support noexcept function types will still work. Only msvc would need to be 
> fixed in some way.
>
> With our traditional approach, I would need to request the addition of 
> BOOST_NO_CXX17_NOEXCEPT_FUNCTION_TYPE, wait for it to be added and to be 
> present on every compiler except the latest ones (which requires changes 
> throughout Boost.Config), and only then be able to use #ifndef 
> BOOST_NO_CXX17_NOEXCEPT_FUNCTION_TYPE. (Then wait for it to be merged to 
> master before merging my changes to master.) 

Of course, boost shouldn't define `__cpp_noexcept_function_type`, but it could
define `BOOST_FEATURE_NOEXCEPT_FUNCTION_TYPE`(or whatever mapping we want to
have from sd-6 macros to boost macros). Using the scheme above, Boost.Bind
could define it if it hasn't already been defined by Boost.Config or the user.
So simply doing:

#ifndef BOOST_FEATURE_NOEXCEPT_FUNCTION_TYPE
#ifdef __cpp_noexcept_function_type
#define BOOST_FEATURE_NOEXCEPT_FUNCTION_TYPE 1
#else
#define BOOST_FEATURE_NOEXCEPT_FUNCTION_TYPE 0
#endif
#endif

This way Boost.Bind can start using that feature while it waits for it to be
integrated in Boost.Config, and then it can remove the macro definition above
once its integrated into Boost.Config.

This does have a potential problem if two libraries decide to define the macro
in different ways, but this should only exists until its integrated into
Boost.Config.


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