On 11/06/17 15:45, Peter Dimov via Boost wrote:
Andrey Semashev wrote:
Boost.Config macros do not necessarilly correspond to what the compiler defines. Compilers lie sometimes by defining a macro while the corresponding feature is broken.
That's true in principle but I've found this practice questionable and can't help but note that in my specific example of __cpp_noexcept_function_type, if Config doesn't define the macro my code will break, regardless of whether the feature is broken. I want to know if the feature is present, not whether someone arbitrarily considers it broken. But that's really a side issue.
I think we had multiple occasions when we disabled a feature that was advertised as implemented in a compiler. Having Boost.Config declaring the feature as available in such cases would not be helpful because the actual code would still not work. You need a macro that indicates that noexcept is part of the function type. I'm not sure how any compiler that supports the feature can support it incompletely/incorrectly, but until we have an actual case we can't tell if that level of support is suitable for you. I'd say add BOOST_NO_CXX17_NOEXCEPT_FUNCTION_TYPES and use it in Boost.Bind the way we always did. When there appears a compiler that doesn't fit, we'll see what is best. It is always possible to add compiler-specific exceptions in Boost.Bind or define a special macro in Boost.Bind.
The objections to the specific idea of defining SD-6 macros in Config are solid, but nobody has said anything about the inefficiencies in our current approach that are caused by us defining negative macros instead of positive ones.
I don't see much of a problem with the negative form. The idea is that the macros indicate compiler defects wrt. the latest standard (plus the positive form macros for non-standard features), which I think makes sense. This way the number of defined macros tend to be always low on good compilers, which is probably better than having them continuously grow over time. Anyway, I'm not particularly tied to either negative or positive form. The process of adding a new macro seems to be the same in either case, so I don't see much difference from the maintenance/submission cost perspective. What I do prefer though is that we have *one* naming approach, consistent across Boost and C++ versions. That significantly reduces the cost of using the macros. We currently use the negative form and I'm guessing we're not going to remove the current macros straight away because of breaking tons of code. So I guess that's a point in favor of the negative form.
We can avoid the problem of not being allowed to define "foreign" macros by having our own names for them and defining them automatically when the standard macro is defined.
#ifdef __cpp_noexcept_function_type # define BOOST_CPP_NOEXCEPT_FUNCTION_TYPE #endif
Positive macros suffer from the problem of one forgetting to include config.hpp a bit more than negative macros do, but using our names avoids the other problem Steven brings up, that things would silently work in this case on g++/clang++.
I'm not sure "forgetting to include config.hpp" is a valid argument. You're obviously using Boost.Config (that follows from the macro name), so you should include its header. This would be less so obvious if we decided to define __cpp_noexcept_function_type ourselves, which is another point against that approach.