This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/79433] __has_include reports wrong result for std headers that #error on __cplusplus
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 09 Feb 2017 02:52:12 +0000
- Subject: [Bug c++/79433] __has_include reports wrong result for std headers that #error on __cplusplus
- Auto-submitted: auto-generated
- References: <bug-79433-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79433
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Marc Mutz from comment #1)
> And no, checking __cplusplus in addition is not an option, since many
> compilers, GCC included (__cplusplus==1, remember?), do not necessarily bump
> __cplusplus when they implement enough core features to make something like
> string_view (which can be implemented in C++11 just fine) work.
I don't follow this comment. The __cplusplus==1 bug was fixed years ago (GCC
4.7.0) and since then the macro has always been bumped when a new -std option
is supported. If it wasn't bumped, the #error directives that are behind this
bug report wouldn't work!
So while some other implementations do make <string_view> available for C++11
mode, GCC is not one of them, and I don't understand the "GCC included" part of
your comment.
If you said that some compilers make <string_view> available without -std=c++17
(or equivalent) so checking __cplusplus > 201402L would prevent using
<string_view> when it's actually usable, then that would be a valid argument.
It's not about bumping __cplusplus or not bumping it, it's about which -std
option is needed for the header to be usable. That varies between compilers, so
checking "__has_include(<string_view> && __cplusplus > 201402L" works, and is
portable, but is overly conservative.
(In reply to Marc Mutz from comment #5)
> Please explain how one should detect, in a portable way, whether string_view
> and experimental::string_view is available, if not by headers check.
These should work portably and correctly:
#ifdef __has_include
#if __has_include(<string_view>) && __cplusplus > 201402L
#ifdef __has_include
#if __has_include(<experimental/string_view>) && __cplusplus >= 201402L
As I said, they're overly conservative, but they shouldn't give false
positives, only false negatives.
I brought the problem up on IRC a few months ago:
<jwakely> would it be unthinkably ugly to give #include hardcoded
knowledge of standard library headers, and which -std option enables them?
<jwakely> so that #include <thread> would automatically skip the stdinc
paths if -std=c++98 ?
<jwakely> otherwise __has_include(<thread>) says yes, but including it
barfs
<jwakely> skipping the stdinc paths would allow users to provide their own
fallbacks for when the standard one is not present (or rather, is present, but
gets skipped)
<jwakely> an alternative would be to put c++11 headers in a new sub-dir of
$includedir/c++/$gccver/ and only add it to the include paths for -std=c++11
and up
<jwakely> and similarly for c++14 and c++17 headers
<jwakely> either solution is a bit smelly
<V-ille> as discussed privately, it seems too smelly to strive for, as
users can check both __cplusplus and __has_include
<V-ille> and once the include part has been thus properly ifdeffed not to
barf, the rest of the code can use a feature macro