[config] Using SD-6 macros
I realize I may be late to the discussion, but what is the reason why Boost.config does not use the SD-6 macro functionality as the first check for all C11 and C14 related configuration options ? Is it because Boost.config feels that the few current SD-6 implementations are buggy ? As I understand SD-6 the implementation of SD-6 itself can always be checked effortlessly by an #if defined(__SOME_SD6_MACRO) before attempting to use the functionality defined by SD-6, so for the majority of compilers which do not implement SD-6 functionality yet Boost.config can always and easily fall back on its current checks. But for those compilers which do implement SD-6 ( latest clang and gcc 5.1.0 ) surely using SD-6 is easier than the many clever ways which Boost.config currently finds out how compilers and standard libraries are configured.
On 12/06/2015 16:21, Edward Diener wrote:
I realize I may be late to the discussion, but what is the reason why Boost.config does not use the SD-6 macro functionality as the first check for all C11 and C14 related configuration options ?
We haven't needed to, and until recently we haven't had implementations to check against. So "history" basically. Plus for compiler features, Clang has __has_feature. For std lib features, we're sort of screwed though - you can't check the SD6 macros without including the std lib header first - and given that we've already gone to great lengths to make it as lightweight as possible, including the whole std lib just to check the SD6 macros is not going to happen. Plus as things stand, I don't see what we gain by duplicating macros which can be checked directly anyway? John.
On 6/12/2015 12:06 PM, John Maddock wrote:
On 12/06/2015 16:21, Edward Diener wrote:
I realize I may be late to the discussion, but what is the reason why Boost.config does not use the SD-6 macro functionality as the first check for all C11 and C14 related configuration options ?
We haven't needed to, and until recently we haven't had implementations to check against. So "history" basically.
Some of it, although very clever, seems like educated "guesswork". Isn't it better if the compiler tells us what is omplemented ?
Plus for compiler features, Clang has __has_feature.
OK, that's reliable, as long as the __has_feature we want to check is actually implemented for a given clang release. Of course that's no different than SD-6 except that has_feature is just clang and SD-6 is meant for everybody.
For std lib features, we're sort of screwed though - you can't check the SD6 macros without including the std lib header first - and given that we've already gone to great lengths to make it as lightweight as possible, including the whole std lib just to check the SD6 macros is not going to happen.
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined. Are you saying that because the compiler implementations of SD-6 most likely have to include standard library headers in order to implement SD-6 correctly that we should avoid using SD-6 ?
Plus as things stand, I don't see what we gain by duplicating macros which can be checked directly anyway?
I do not believe the direct checks are as reliable as SD-6. If I look at libcpp.hpp we are just checking __cplusplus for a bunch of c11 features and libraries. That seems pretty hit and miss to me. When I asked about a way to check libc++ features for any given libc++ release in the clang mailing list the answer was to use SD-6 as a first line of checking. In libstdcpp3.hpp we are doing a much cleverer way of checking, but again when I asked about it on the gcc developers mailing list I was told to use SD-6 if it was available first. I understand all the work you and others have put into Boost.config and I am not suggesting that we replace all of Boost.config's checking simply by SD-6, since it is likely to be ages before every compiler supports SD-6, but SD-6 seems like a much more reliable first way of checking a number of features/headers than we are now doing.
Edward Diener wrote:
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined.
All __cpp_lib macros have an associated header, although I don't know if we currently have Boost.Config equivalents for any of them. It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
On 6/12/2015 1:05 PM, Peter Dimov wrote:
Edward Diener wrote:
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined.
All __cpp_lib macros have an associated header, although I don't know if we currently have Boost.Config equivalents for any of them.
I can see them but they are all C++14 features. Are we really objecting to including a particular standard library header in order to test for the existence of the equivalent SD-6 macro ? If so I think we are dead wrong to raise that objection unless we have an absolutely sure way of knowing for the particular compiler implementation outside of SD-6.
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
On 13.06.2015 05:26, Edward Diener wrote:
On 6/12/2015 1:05 PM, Peter Dimov wrote:
All __cpp_lib macros have an associated header, although I don't know if we currently have Boost.Config equivalents for any of them.
I can see them but they are all C++14 features. Are we really objecting to including a particular standard library header in order to test for the existence of the equivalent SD-6 macro ?
Yes, that would be the objection from my side, at least. I don't want to include a whole std header to check for a single feature that may be implemented in it. And I want Boost.Config to include most of STL even less.
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
For a compiler that does not support SD-6 you would end up with "the compiler does not support C++" with this approach. :) Seriously, you do have to know when to check those macros, if you want to know the actual capabilities of the compiler. I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
On 6/13/2015 2:22 AM, Andrey Semashev wrote:
I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
2c: For each feature test, we would need both (e.g.) __cpp_constexpr and __cpp_constexpr_and_implemented_correctly. The chance of just (e.g.) __cpp_constexpr being reliable enough is low, IMO, particularly for non-trivial feature use (e.g. Boost). Regards, Paul Mensonides
On 13.06.2015 12:31, Paul Mensonides wrote:
On 6/13/2015 2:22 AM, Andrey Semashev wrote:
I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
2c:
For each feature test, we would need both (e.g.) __cpp_constexpr and __cpp_constexpr_and_implemented_correctly. The chance of just (e.g.) __cpp_constexpr being reliable enough is low, IMO, particularly for non-trivial feature use (e.g. Boost).
Exactly.
On 6/13/2015 5:31 AM, Paul Mensonides wrote:
On 6/13/2015 2:22 AM, Andrey Semashev wrote:
I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
2c:
For each feature test, we would need both (e.g.) __cpp_constexpr and __cpp_constexpr_and_implemented_correctly. The chance of just (e.g.) __cpp_constexpr being reliable enough is low, IMO, particularly for non-trivial feature use (e.g. Boost).
What you are saying is that we can use SD-6 but that we shouldn't trust that whoever implements it is doing it correctly.
On 13 Jun 2015 at 11:27, Edward Diener wrote:
For each feature test, we would need both (e.g.) __cpp_constexpr and __cpp_constexpr_and_implemented_correctly. The chance of just (e.g.) __cpp_constexpr being reliable enough is low, IMO, particularly for non-trivial feature use (e.g. Boost).
What you are saying is that we can use SD-6 but that we shouldn't trust that whoever implements it is doing it correctly.
Both GCC and clang have been lenient in letting you use some minor C++ 14 constexpr when in C++ 11 constexpr mode (albeit usually with a warning). VS2015 will not be lenient. You get guaranteed as much constexpr as is minimally required to implement C++ 11, anything past that is gravy. I've tried feeding test code into the unreleased full constexpr web MSVC compiler and so far for me at least it's working. I would like to assume someone in Microsoft has tried flipping BOOST_CONSTEXPR on in Boost with their latest release, but maybe STL can tell us more on that. One ballsy move might be for Boost to turn on BOOST_CONSTEXPR unilaterally for VS2015, and let the bug reports work their magic :) Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 6/13/2015 5:22 AM, Andrey Semashev wrote:
On 13.06.2015 05:26, Edward Diener wrote:
On 6/12/2015 1:05 PM, Peter Dimov wrote:
All __cpp_lib macros have an associated header, although I don't know if we currently have Boost.Config equivalents for any of them.
I can see them but they are all C++14 features. Are we really objecting to including a particular standard library header in order to test for the existence of the equivalent SD-6 macro ?
Yes, that would be the objection from my side, at least. I don't want to include a whole std header to check for a single feature that may be implemented in it. And I want Boost.Config to include most of STL even less.
And the rationale for this is what ? Compile-time computer cycles ?
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
For a compiler that does not support SD-6 you would end up with "the compiler does not support C++" with this approach. :) Seriously, you do have to know when to check those macros, if you want to know the actual capabilities of the compiler.
Of course the SD-6 macro is checked when you need it, not just blindly for no reason.
I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
I am not suggesting replacing Boost.config with SD-6. But as C++ moves on in the future SD-6 provides a more fail-safe methodology than the wizardry/hackery of current Boost.config.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On June 13, 2015 10:10:56 AM EDT, Edward Diener
On 6/13/2015 5:22 AM, Andrey Semashev wrote:
On 13.06.2015 05:26, Edward Diener wrote:
On 6/12/2015 1:05 PM, Peter Dimov wrote:
All __cpp_lib macros have an associated header, although I don't
know if
we currently have Boost.Config equivalents for any of them.
I can see them but they are all C++14 features. Are we really objecting to including a particular standard library header in order to test for the existence of the equivalent SD-6 macro ?
Yes, that would be the objection from my side, at least. I don't want to include a whole std header to check for a single feature that may be implemented in it. And I want Boost.Config to include most of STL even less.
And the rationale for this is what ? Compile-time computer cycles ?
Build times matter too large projects, CI build machines, etc. Extraneous includes are a real issue. Many Boost libraries are pinged for long build times. Includes have measurable affect on that, though perhaps not large. Ignoring those effects is not helpful and could lead to users abandoning Boost libraries. ___ Rob (Sent from my portable computation engine)
Yes, that would be the objection from my side, at least. I don't want to include a whole std header to check for a single feature that may be implemented in it. And I want Boost.Config to include most of STL even less.
And the rationale for this is what ? Compile-time computer cycles ?
The effect is measurable, at least on cygwin GCC-4.9.2, I see: Current Config Size: 21K, times: real 0m0.279s user 0m0.030s sys 0m0.233s Config plus headers required for current SD6: Size 2Mb, times: real 0m1.092s user 0m0.593s sys 0m0.467s I would expect the effect to get worse as more SD6 macros are added to other headers. John.
On 13.06.2015 17:10, Edward Diener wrote:
On 6/13/2015 5:22 AM, Andrey Semashev wrote:
On 13.06.2015 05:26, Edward Diener wrote:
On 6/12/2015 1:05 PM, Peter Dimov wrote:
All __cpp_lib macros have an associated header, although I don't know if we currently have Boost.Config equivalents for any of them.
I can see them but they are all C++14 features. Are we really objecting to including a particular standard library header in order to test for the existence of the equivalent SD-6 macro ?
Yes, that would be the objection from my side, at least. I don't want to include a whole std header to check for a single feature that may be implemented in it. And I want Boost.Config to include most of STL even less.
And the rationale for this is what ? Compile-time computer cycles ?
Yes.
On 13 Jun 2015 at 12:22, Andrey Semashev wrote:
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
For a compiler that does not support SD-6 you would end up with "the compiler does not support C++" with this approach. :) Seriously, you do have to know when to check those macros, if you want to know the actual capabilities of the compiler.
APIBind enforces a consistent and correct set of SD-6 language feature macros on all versions of clang, GCC and MSVC using https://github.com/ned14/Boost.APIBind/blob/master/include/cpp_feature .h. It then uses those SD-6 macros to create a partial emulation of Boost Config in https://github.com/ned14/Boost.APIBind/blob/master/include/boost/confi g.hpp.
I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
Also, if I remember correctly an unadvertised feature of Boost.Config is that it is completely standalone capable. You can include it as a git submodule to your project and use it for compiler detection without any requirement on the rest of Boost. I think SD-6 macros are relevant for detecting very new C++ language features, apart from that their usefulness is limited. I find in particular the library feature detection macros to be almost useless in the real world as what you actually do in practice is target a certain minimum standard library featureset, so if the code compiles it does if not then it doesn't. You don't write #ifdef code for multiple standard library versions usually as it's just easiest to swap in Boost if you can't rely on your standard library i.e. you either mandate a Boost dependency or a minimum standard library featureset, you don't have your code self adjust to library availability as you would language feature availability (usually). Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 6/13/2015 11:45 AM, Niall Douglas wrote:
On 13 Jun 2015 at 12:22, Andrey Semashev wrote:
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
For a compiler that does not support SD-6 you would end up with "the compiler does not support C++" with this approach. :) Seriously, you do have to know when to check those macros, if you want to know the actual capabilities of the compiler.
APIBind enforces a consistent and correct set of SD-6 language feature macros on all versions of clang, GCC and MSVC using https://github.com/ned14/Boost.APIBind/blob/master/include/cpp_feature .h. It then uses those SD-6 macros to create a partial emulation of Boost Config in https://github.com/ned14/Boost.APIBind/blob/master/include/boost/confi g.hpp.
I can see SD-6 only as a helper tool for libraries like Boost.Config and not as an alternative. We had various version and feature checks in Boost.Config for years, it worked wonderfully and I don't see why it would break for the existing compilers we support. Future compilers may add features that are currently missing, and we will have to update Boost.Config accordingly, whether the compilers use SD-6, misuse it or not use it at all.
Also, if I remember correctly an unadvertised feature of Boost.Config is that it is completely standalone capable. You can include it as a git submodule to your project and use it for compiler detection without any requirement on the rest of Boost.
What does config being standalone capable have to do with SD-6 ? I do not recall that SD-6 has anything to do with using other Boost libraries, do you ?
I think SD-6 macros are relevant for detecting very new C++ language features, apart from that their usefulness is limited. I find in particular the library feature detection macros to be almost useless in the real world as what you actually do in practice is target a certain minimum standard library featureset, so if the code compiles it does if not then it doesn't. You don't write #ifdef code for multiple standard library versions usually as it's just easiest to swap in Boost if you can't rely on your standard library i.e. you either mandate a Boost dependency or a minimum standard library featureset, you don't have your code self adjust to library availability as you would language feature availability (usually).
On June 12, 2015 10:26:49 PM EDT, Edward Diener
On 6/12/2015 1:05 PM, Peter Dimov wrote:
Edward Diener wrote:
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
If the absence of an SD-6 macro implies a feature is not implemented, then the absence of SD-6 support indicates nothing is implemented when that's the mechanism used for discovery of features. ___ Rob (Sent from my portable computation engine)
On 6/13/2015 7:13 AM, Rob Stewart wrote:
On June 12, 2015 10:26:49 PM EDT, Edward Diener
wrote: On 6/12/2015 1:05 PM, Peter Dimov wrote:
Edward Diener wrote:
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
If the absence of an SD-6 macro implies a feature is not implemented, then the absence of SD-6 support indicates nothing is implemented when that's the mechanism used for discovery of features.
But who cares ? Each SD=6 feature test stands on its own. I could care less if a determination is made "somehow" that SD-6 as a whole is not implemented. It doesn't buy me anything.
On June 13, 2015 10:01:33 AM EDT, Edward Diener
On 6/13/2015 7:13 AM, Rob Stewart wrote:
On June 12, 2015 10:26:49 PM EDT, Edward Diener
wrote: On 6/12/2015 1:05 PM, Peter Dimov wrote:
Edward Diener wrote:
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
If the absence of an SD-6 macro implies a feature is not implemented, then the absence of SD-6 support indicates nothing is implemented when that's the mechanism used for discovery of features.
But who cares ? Each SD=6 feature test stands on its own. I could care less if a determination is made "somehow" that SD-6 as a whole is not implemented. It doesn't buy me anything.
You're missing the point. If you can't determine whether SD-6 is available, then you can't just check for the presence of an SD-6 macro to decide whether a feature is available. If the macro isn't present, but SD-6 is supported, then the feature isn't available. If SD-6 isn't supported, then you don't know the answer. Maybe you mean to try an SD-6 macro to see that a feature is implemented and, if that fails, try other methods before giving up and declaring the feature missing. I suppose that a positive answer from an SD-6 macro could be more reliable, but that doesn't account for buggy support that Boost can't use. ___ Rob (Sent from my portable computation engine)
On 6/13/2015 11:32 AM, Rob Stewart wrote:
On June 13, 2015 10:01:33 AM EDT, Edward Diener
wrote: On 6/13/2015 7:13 AM, Rob Stewart wrote:
On June 12, 2015 10:26:49 PM EDT, Edward Diener
wrote: On 6/12/2015 1:05 PM, Peter Dimov wrote:
Edward Diener wrote:
It seems to me that there's no macro for SD-6 itself though. When __cpp_something is not defined, you don't know whether this is because 'something' is not implemented or because SD-6 is not implemented.
What difference could it possibly make ? You test if a macro is defined and if it is not you try something else. If it is you have your answer.
If the absence of an SD-6 macro implies a feature is not implemented, then the absence of SD-6 support indicates nothing is implemented when that's the mechanism used for discovery of features.
But who cares ? Each SD=6 feature test stands on its own. I could care less if a determination is made "somehow" that SD-6 as a whole is not implemented. It doesn't buy me anything.
You're missing the point. If you can't determine whether SD-6 is available, then you can't just check for the presence of an SD-6 macro to decide whether a feature is available. If the macro isn't present, but SD-6 is supported, then the feature isn't available. If SD-6 isn't supported, then you don't know the answer.
Maybe you mean to try an SD-6 macro to see that a feature is implemented and, if that fails, try other methods before giving up and declaring the feature missing.
Yes, that is how I intended SD-6 should be used in Boost.config. I have explained that numerous times in my replies on this thread.
I suppose that a positive answer from an SD-6 macro could be more reliable, but that doesn't account for buggy support that Boost can't use.
Of course not but we already deal with buggy support anyway in config. I do not mean to replace config's knowledge now or in the future of buggy support for compiler features with blind trust in whatever SD-6 says or whatever a particular compiler or standard library says. If we empirically know that some feature or standard library implementations is not working we mark it accordingly in config. Nothing whatever changes in config if we use SD-6 where appropriate in this respect.
On 12/06/2015 17:53, Edward Diener wrote:
On 6/12/2015 12:06 PM, John Maddock wrote:
On 12/06/2015 16:21, Edward Diener wrote:
I realize I may be late to the discussion, but what is the reason why Boost.config does not use the SD-6 macro functionality as the first check for all C11 and C14 related configuration options ?
We haven't needed to, and until recently we haven't had implementations to check against. So "history" basically.
Some of it, although very clever, seems like educated "guesswork". Isn't it better if the compiler tells us what is omplemented ?
Sure, but like I said, this has only been very recently supported.
Plus for compiler features, Clang has __has_feature.
OK, that's reliable, as long as the __has_feature we want to check is actually implemented for a given clang release. Of course that's no different than SD-6 except that has_feature is just clang and SD-6 is meant for everybody.
For std lib features, we're sort of screwed though - you can't check the SD6 macros without including the std lib header first - and given that we've already gone to great lengths to make it as lightweight as possible, including the whole std lib just to check the SD6 macros is not going to happen.
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined. Are you saying that because the compiler implementations of SD-6 most likely have to include standard library headers in order to implement SD-6 correctly that we should avoid using SD-6 ?
No, I'm saying we can't check the __cpp_lib* macros without: a) using __has_include to check the header exists, then b) actually including the header.
Plus as things stand, I don't see what we gain by duplicating macros which can be checked directly anyway?
I do not believe the direct checks are as reliable as SD-6.
What I mean is: If we don't have a macro for something, but SD6 does, then the user can just check SD6 without using Boost.Config at all.
If I look at libcpp.hpp we are just checking __cplusplus for a bunch of c11 features and libraries. That seems pretty hit and miss to me. When I asked about a way to check libc++ features for any given libc++ release in the clang mailing list the answer was to use SD-6 as a first line of checking. Looks like we could do better for some of those: where the compiler is clang anyway. Note the comment though that some of the headers exist, but are broken. Given that there are no useful libc++ (or clang) version numbers available, I don't know what we do about that :( In libstdcpp3.hpp we are doing a much cleverer way of checking, but again when I asked about it on the gcc developers mailing list I was told to use SD-6 if it was available first.
For GCC5 and later yes, but again, there's very little overlap between our config macros and SD6 lib macros at present - GCC5 basically doesn't define anything much in libstdcpp.hpp? John.
I understand all the work you and others have put into Boost.config and I am not suggesting that we replace all of Boost.config's checking simply by SD-6, since it is likely to be ages before every compiler supports SD-6, but SD-6 seems like a much more reliable first way of checking a number of features/headers than we are now doing.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 6/12/2015 2:49 PM, John Maddock wrote:
On 12/06/2015 17:53, Edward Diener wrote:
On 6/12/2015 12:06 PM, John Maddock wrote:
On 12/06/2015 16:21, Edward Diener wrote:
I realize I may be late to the discussion, but what is the reason why Boost.config does not use the SD-6 macro functionality as the first check for all C11 and C14 related configuration options ?
We haven't needed to, and until recently we haven't had implementations to check against. So "history" basically.
Some of it, although very clever, seems like educated "guesswork". Isn't it better if the compiler tells us what is omplemented ?
Sure, but like I said, this has only been very recently supported.
I understand that.
Plus for compiler features, Clang has __has_feature.
OK, that's reliable, as long as the __has_feature we want to check is actually implemented for a given clang release. Of course that's no different than SD-6 except that has_feature is just clang and SD-6 is meant for everybody.
For std lib features, we're sort of screwed though - you can't check the SD6 macros without including the std lib header first - and given that we've already gone to great lengths to make it as lightweight as possible, including the whole std lib just to check the SD6 macros is not going to happen.
Each particular check does not include the whole std lib. Are you really objecting to including individual headers for individual features if there is no absolutely reliable method otherwise ?
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined. Are you saying that because the compiler implementations of SD-6 most likely have to include standard library headers in order to implement SD-6 correctly that we should avoid using SD-6 ?
No, I'm saying we can't check the __cpp_lib* macros without:
a) using __has_include to check the header exists, then b) actually including the header.
Plus as things stand, I don't see what we gain by duplicating macros which can be checked directly anyway?
So we let each Boost library and each end-user of Boost go through the mechanism of checking a C++14 feature using SD-6 themselves rather than doing it once in Boost.config ?
I do not believe the direct checks are as reliable as SD-6.
What I mean is:
If we don't have a macro for something, but SD6 does, then the user can just check SD6 without using Boost.Config at all.
See my previous argument just above.
If I look at libcpp.hpp we are just checking __cplusplus for a bunch of c11 features and libraries. That seems pretty hit and miss to me. When I asked about a way to check libc++ features for any given libc++ release in the clang mailing list the answer was to use SD-6 as a first line of checking. Looks like we could do better for some of those: where the compiler is clang anyway. Note the comment though that some of the headers exist, but are broken. Given that there are no useful libc++ (or clang) version numbers available, I don't know what we do about that :(
I brought up the "no useful libc++ version numbers" with the libc++ developers and Richard Smith was vociferous in saying to use SD-6 as they are not going to be backporting anything in libc++ in the face of SD-6.
In libstdcpp3.hpp we are doing a much cleverer way of checking, but again when I asked about it on the gcc developers mailing list I was told to use SD-6 if it was available first.
For GCC5 and later yes, but again, there's very little overlap between our config macros and SD6 lib macros at present - GCC5 basically doesn't define anything much in libstdcpp.hpp?
Your feeling then is that we should not try to do anything in Boost.config for C++14 features/headers or possiblly C++17 features/headers if they are already covered by SD-6 ? What about C++11 features and headers we already have in Boost.config ? You don't see them as being more reliable if we go the SD-6 route and only fallback to our current implementation if SD-6 is not available ? I am concerned because some of our current implementation seems both awfully fragile and an awful amount of continuing work as new compiler releases come out, whereas SD-6 offers a solution to much of that "drudgery" <g>. And you don't seem to want to take that solution.
John.
I understand all the work you and others have put into Boost.config and I am not suggesting that we replace all of Boost.config's checking simply by SD-6, since it is likely to be ages before every compiler supports SD-6, but SD-6 seems like a much more reliable first way of checking a number of features/headers than we are now doing.
Each particular check does not include the whole std lib. Are you really objecting to including individual headers for individual features if there is no absolutely reliable method otherwise ?
Well the question is "is there a reliable method otherwise"? There may well not be for clang/libstdc++ but for everything else I'm fairly sure there is. BTW this is not my objection so much as I can tell you from past experience that users absolutely do complain if Boost.Config starts #including too much. Were we to duplicate all the SD6 macros then we would have to include all of: utility memory functional type_traits chrono string map set iterator algorithm complex iomanip shared_mutex Are you suggesting that would be a good idea for a library that just wants to check if |BOOST_NO_LONG_LONG is set? There are obviously other solutions - separate headers for this stuff for example - but we're not there yet - remember that we only tend to add new macros when libraries actually need them, not as vaporware. |
So we let each Boost library and each end-user of Boost go through the mechanism of checking a C++14 feature using SD-6 themselves rather than doing it once in Boost.config ?
There's little difference: #ifdef |__cpp_lib_integer_sequence https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... against #ifndef BOOST_NOCPP_LIB_INTEGER_SEQUENCE Obviously if we find SD6 implementations buggy then we'll have to revisit. |
Your feeling then is that we should not try to do anything in Boost.config for C++14 features/headers or possiblly C++17 features/headers if they are already covered by SD-6 ? What about C++11 features and headers we already have in Boost.config ? You don't see them as being more reliable if we go the SD-6 route and only fallback to our current implementation if SD-6 is not available ?
Please be specific, there are already some SD6 checks in the compiler configs I believe, and like I said for std lib checks are you suggesting that SD6 is better / less buggy than __has_feature for clang? For GCC we need the version check to verify that SD6 exists, and then... *nothing happens*, as we don't don't set anything anyway for gcc-5.1 as far as I can remember. John.
On 6/13/2015 4:12 AM, John Maddock wrote:
Each particular check does not include the whole std lib. Are you really objecting to including individual headers for individual features if there is no absolutely reliable method otherwise ?
Well the question is "is there a reliable method otherwise"? There may well not be for clang/libstdc++ but for everything else I'm fairly sure there is.
Unless individual compilers and/or standard libraries continue to provide "a reliable method" for future releases outside of SD-6 it sure seems easier to me to rely on an SD-6 implementation as the first check.
BTW this is not my objection so much as I can tell you from past experience that users absolutely do complain if Boost.Config starts #including too much. Were we to duplicate all the SD6 macros then we would have to include all of:
utility memory functional type_traits chrono string map set iterator algorithm complex iomanip shared_mutex
I think it is the fault of users to complain about this. Clearly SD-6 did not think that including a header to find out if a particular feature was available or not is not a great inconvenience.
Are you suggesting that would be a good idea for a library that just wants to check if |BOOST_NO_LONG_LONG is set?
Agreed in principal but I don't think it can be avoided easily in reality.
There are obviously other solutions - separate headers for this stuff for example - but we're not there yet - remember that we only tend to add new macros when libraries actually need them, not as vaporware. |
Agreed.
So we let each Boost library and each end-user of Boost go through the mechanism of checking a C++14 feature using SD-6 themselves rather than doing it once in Boost.config ?
There's little difference:
#ifdef |__cpp_lib_integer_sequence https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat...
against
#ifndef BOOST_NOCPP_LIB_INTEGER_SEQUENCE
Obviously if we find SD6 implementations buggy then we'll have to revisit. |
I would have thought the correct SD-6 code for this is: #ifdef __has_include #if __has_include(<utility>) #include <utility> #if __cpp_lib_integer_sequence #endif #endif #endif
Your feeling then is that we should not try to do anything in Boost.config for C++14 features/headers or possiblly C++17 features/headers if they are already covered by SD-6 ? What about C++11 features and headers we already have in Boost.config ? You don't see them as being more reliable if we go the SD-6 route and only fallback to our current implementation if SD-6 is not available ?
Please be specific, there are already some SD6 checks in the compiler configs I believe, and like I said for std lib checks are you suggesting that SD6 is better / less buggy than __has_feature for clang?
I mentioned libc++, Even the checks in libstdc++ are heavily reliant on interpreting gcc "versions" from other compilers which use libstdc++, like clang. Suppose other compilers start using libstdc++ ? Looking at Dinkumware we are currently relying on an internal version number for C11 features. I am not really criticizing as I know how much work you and others have done to make config work as well as it does.
For GCC we need the version check to verify that SD6 exists, and then... *nothing happens*, as we don't don't set anything anyway for gcc-5.1 as far as I can remember.
You don't ever have to do a version check for SD-6 if you just try out an SD-6 macro. If it is not defined you just move on to what we are doing now in Boost.config, for any given situation. I totally agree that we should look at each config feature individually to see if there is an SD-6 equivalent we can possible use. I also agree that as always we shouldn't just be blindly adding features to config just because they exist if nobody is asking for them. My point of view is that for any config feature which has an SD-6 equivalence, unless you absolutely believe that there is a fail-safe method of testing for that feature for a given compiler and/or standard library both now and in the future, we can use SD-6 as the first check for the feature that we do before we move on to our current check if the SD-6 feature check does not exist. I view this as more robust now and for the future.
Obviously if we find SD6 implementations buggy then we'll have to revisit. |
I would have thought the correct SD-6 code for this is:
#ifdef __has_include #if __has_include(<utility>) #include <utility> #if __cpp_lib_integer_sequence #endif #endif #endif
Only if you're being unreasonably pedantic - I don't think there are any compilers supporting SD6 that don't have <utility> - or indeed any of the other headers mentioned in SD6 for that matter. The point is, if you're the end user, you're going to have to include <utility> or whatever anyway, so including it before checking the SD6 macro for whatever "advanced" feature you're interested in loses you nothing. Boost.Config on the other hand would have to #include everything regardless of whether it's being used or not.
I mentioned libc++, Even the checks in libstdc++ are heavily reliant on interpreting gcc "versions" from other compilers which use libstdc++, like clang. Suppose other compilers start using libstdc++ ? Looking at Dinkumware we are currently relying on an internal version number for C11 features.
Edward, I'm sorry but this is all hypothetical at present - we will do whatever needs to be done to make things work - that will surely include some use of SD6 (especially the compiler-predefined macros). What I'm trying to get across is that there is little overlap between current Boost.Config macros and SD6 - so the opportunities for simplification of what we have are extremely thin on the ground. And you're correct that the libstdc++ config is pretty darn tricky - but SD6 doesn't help us a bit for say Clang on libstdc++ - we can't use simple __has_include to check for the existence of std lib headers because many were hopelessly buggy when first introduced. We can't use any compiler intrinsic defines (SD6 or otherwise) because they have no relation to the std lib. We can't use libstdc++ version numbers because they're simple release dates that have no correspondence to GCC version and/or feature sets. So that leaves us back with trying to infer the GCC release as now - and once you have that you have the info you need to configure anyway.
I am not really criticizing as I know how much work you and others have done to make config work as well as it does.
For GCC we need the version check to verify that SD6 exists, and then... *nothing happens*, as we don't don't set anything anyway for gcc-5.1 as far as I can remember.
You don't ever have to do a version check for SD-6 if you just try out an SD-6 macro. If it is not defined you just move on to what we are doing now in Boost.config, for any given situation.
Unfortunately that's not quite true - sometimes you can't reliably include a std lib header even when __has_include reports true as noted above. John.
I totally agree that we should look at each config feature individually to see if there is an SD-6 equivalent we can possible use. I also agree that as always we shouldn't just be blindly adding features to config just because they exist if nobody is asking for them.
My point of view is that for any config feature which has an SD-6 equivalence, unless you absolutely believe that there is a fail-safe method of testing for that feature for a given compiler and/or standard library both now and in the future, we can use SD-6 as the first check for the feature that we do before we move on to our current check if the SD-6 feature check does not exist. I view this as more robust now and for the future.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost .
On 6/13/2015 1:28 PM, John Maddock wrote:
Obviously if we find SD6 implementations buggy then we'll have to revisit. |
I would have thought the correct SD-6 code for this is:
#ifdef __has_include #if __has_include(<utility>) #include <utility> #if __cpp_lib_integer_sequence #endif #endif #endif
Only if you're being unreasonably pedantic - I don't think there are any compilers supporting SD6 that don't have <utility> - or indeed any of the other headers mentioned in SD6 for that matter.
The point is, if you're the end user, you're going to have to include <utility> or whatever anyway, so including it before checking the SD6 macro for whatever "advanced" feature you're interested in loses you nothing. Boost.Config on the other hand would have to #include everything regardless of whether it's being used or not.
I agree that is a good argument against using those macros. There are some solutions, but they all entail inconvenience to the user of config. But until an individual case might be considered I will refrain from suggesting any possible solutions.
I mentioned libc++, Even the checks in libstdc++ are heavily reliant on interpreting gcc "versions" from other compilers which use libstdc++, like clang. Suppose other compilers start using libstdc++ ? Looking at Dinkumware we are currently relying on an internal version number for C11 features.
Edward, I'm sorry but this is all hypothetical at present - we will do whatever needs to be done to make things work - that will surely include some use of SD6 (especially the compiler-predefined macros).
Good.
What I'm trying to get across is that there is little overlap between current Boost.Config macros and SD6 - so the opportunities for simplification of what we have are extremely thin on the ground.
Understood.
And you're correct that the libstdc++ config is pretty darn tricky - but SD6 doesn't help us a bit for say Clang on libstdc++ - we can't use simple __has_include to check for the existence of std lib headers because many were hopelessly buggy when first introduced. We can't use any compiler intrinsic defines (SD6 or otherwise) because they have no relation to the std lib. We can't use libstdc++ version numbers because they're simple release dates that have no correspondence to GCC version and/or feature sets. So that leaves us back with trying to infer the GCC release as now - and once you have that you have the info you need to configure anyway.
I am not really criticizing as I know how much work you and others have done to make config work as well as it does.
For GCC we need the version check to verify that SD6 exists, and then... *nothing happens*, as we don't don't set anything anyway for gcc-5.1 as far as I can remember.
You don't ever have to do a version check for SD-6 if you just try out an SD-6 macro. If it is not defined you just move on to what we are doing now in Boost.config, for any given situation.
Unfortunately that's not quite true - sometimes you can't reliably include a std lib header even when __has_include reports true as noted above.
You chided me for not being specific so now I will chide you. Please point out to me one case or more where the SD-6 implementation is buggy in this respect. I don't mean that the header is buggy, because that's something that config rightly deals with, but that __has_include tells you that a header exists where it does not. I don't think that situation exists and if it did it would be a serious compiler implementation of an SD-6 implementation error. Just to finish what I hope is more of an agreement than a disagreement about anything regarding SD-6, as I understand you in this area and I believe you understand me, I am not blindly just advocating SD-6 to tell us everything about everything it can and then just have config just accept it as the final word. I got a lot of flac <g> when I queried in the libc++ and libstdc++ mailing lists to find out how to decide if shared_mutex was part of any given library implementation either now or in the future. The answer I received from libc++ was an absolutely unequivocal one that SD-6 is the only way you will ever find out with certainty, other than an empirical test with a particular compiler's implementation that uses libc++, whether a libc++ implementation supports any given standard library feature. With libstdc++ I received much the same answer to use SD-6 in the future, even though I can plainly see now that gcc 4.9.n includes standard_mutex but SD-6 is not implemented until gcc-5.1. With Dinkumware I could not find out anything, but evidently Dinkumware is VC++ for all Boost's intents and purposes so what is decided is based on VC++ releases. Still even here I feel like its pretty difficult since it seems all empirical with each VC++ release. I felt, not entirely naively, that SD-6 where appropriate, would be a solution.
John.
I totally agree that we should look at each config feature individually to see if there is an SD-6 equivalent we can possible use. I also agree that as always we shouldn't just be blindly adding features to config just because they exist if nobody is asking for them.
My point of view is that for any config feature which has an SD-6 equivalence, unless you absolutely believe that there is a fail-safe method of testing for that feature for a given compiler and/or standard library both now and in the future, we can use SD-6 as the first check for the feature that we do before we move on to our current check if the SD-6 feature check does not exist. I view this as more robust now and for the future.
On 13.06.2015 21:44, Edward Diener wrote:
On 6/13/2015 1:28 PM, John Maddock wrote:
Unfortunately that's not quite true - sometimes you can't reliably include a std lib header even when __has_include reports true as noted above.
You chided me for not being specific so now I will chide you. Please point out to me one case or more where the SD-6 implementation is buggy in this respect. I don't mean that the header is buggy, because that's something that config rightly deals with, but that __has_include tells you that a header exists where it does not.
One example is the <regex> header which existed in libstdc++ bundled with gcc 4.8 (not sure if it was added to earlier gcc versions) but was unusable until 4.9. Although gcc didn't support SD-6 in those versions, one could use clang with libstdc++.
Edward Diener wrote:
On 6/12/2015 12:06 PM, John Maddock wrote: Some of it, although very clever, seems like educated "guesswork". Isn't it better if the compiler tells us what is omplemented ?
For come compiler versions/cxx features the answer is no: For some Clang releases which support SD-6 macros, they didn't implement the SD-6 macro for features which they documented as available. In some cases, they implemented the __has_feature macro for a feature but not the SD-6, and in other cases vice-versa.
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined. Are you saying that because the compiler implementations of SD-6 most likely have to include standard library headers in order to implement SD-6 correctly that we should avoid using SD-6 ?
The reason for this is literally that the chair of SG-10 didn't want to require the stdlib implementor to have to open another file in their editor to add the macro there. http://thread.gmane.org/gmane.comp.lang.c++.isocpp.features/17/focus=22 I get headaches thinking of all the reasons that that's absurd. Thanks, Steve.
Stephen Kelly wrote:
The reason for this is literally that the chair of SG-10 didn't want to require the stdlib implementor to have to open another file in their editor to add the macro there.
http://thread.gmane.org/gmane.comp.lang.c++.isocpp.features/17/focus=22
I get headaches thinking of all the reasons that that's absurd.
It's not just the editor. You could have a configuration in which some stdlib headers come from one place and some from another. Although one could argue that this isn't a reason enough, and I might be inclined to agree.
Peter Dimov wrote:
Stephen Kelly wrote:
The reason for this is literally that the chair of SG-10 didn't want to require the stdlib implementor to have to open another file in their editor to add the macro there.
http://thread.gmane.org/gmane.comp.lang.c++.isocpp.features/17/focus=22
I get headaches thinking of all the reasons that that's absurd.
It's not just the editor. You could have a configuration in which some stdlib headers come from one place and some from another. Although one could argue that this isn't a reason enough, and I might be inclined to agree.
You would? Wow. Ok.
On June 13, 2015 2:30:51 AM EDT, Stephen Kelly
Peter Dimov wrote:
Stephen Kelly wrote:
The reason for this is literally that the chair of SG-10 didn't want to require the stdlib implementor to have to open another file in their editor to add the macro there.
It's not just the editor. You could have a configuration in which some stdlib headers come from one place and some from another. Although one could argue that this isn't a reason enough, and I might be inclined to agree.
You would? Wow. Ok.
I suspect you didn't read Peter's statement correctly. He was saying he's inclined to agree that headers coming from multiple places is not a sufficient reason for embedding the SD-6 macro in the various standard library headers instead of in one. ___ Rob (Sent from my portable computation engine)
Rob Stewart wrote:
On June 13, 2015 2:30:51 AM EDT, Stephen Kelly
wrote: Peter Dimov wrote:
Stephen Kelly wrote:
The reason for this is literally that the chair of SG-10 didn't want to require the stdlib implementor to have to open another file in their editor to add the macro there.
It's not just the editor. You could have a configuration in which some stdlib headers come from one place and some from another. Although one could argue that this isn't a reason enough, and I might be inclined to agree.
You would? Wow. Ok.
I suspect you didn't read Peter's statement correctly. He was saying he's inclined to agree that headers coming from multiple places is not a sufficient reason for embedding the SD-6 macro in the various standard library headers instead of in one.
I think you're right, thanks! Sorry for misreading. Steve.
On 6/12/2015 6:54 PM, Stephen Kelly wrote:
Edward Diener wrote:
On 6/12/2015 12:06 PM, John Maddock wrote: Some of it, although very clever, seems like educated "guesswork". Isn't it better if the compiler tells us what is omplemented ?
For come compiler versions/cxx features the answer is no: For some Clang releases which support SD-6 macros, they didn't implement the SD-6 macro for features which they documented as available.
As long as they don't give the wrong answer for the SD-6 they implemented it does not matter.
In some cases, they implemented the __has_feature macro for a feature but not the SD-6, and in other cases vice-versa.
My view is to use SD-6 and fall back to our current implementation when it is not available.
About what std lib features are you speaking ? Most of the things I see at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat... are predefined. Are you saying that because the compiler implementations of SD-6 most likely have to include standard library headers in order to implement SD-6 correctly that we should avoid using SD-6 ?
The reason for this
"this" meaning what ? That predefined macros are enforced rather than macros in standard library headers ?
is literally that the chair of SG-10 didn't want to require the stdlib implementor to have to open another file in their editor to add the macro there.
http://thread.gmane.org/gmane.comp.lang.c++.isocpp.features/17/focus=22
I get headaches thinking of all the reasons that that's absurd.
participants (9)
-
Andrey Semashev
-
Edward Diener
-
John Maddock
-
Niall Douglas
-
Paul Mensonides
-
Peter Dimov
-
Rob Stewart
-
Stephan T. Lavavej
-
Stephen Kelly