|
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