This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/79433] __has_include reports wrong result for std headers that #error on __cplusplus


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]