C++ Logo

sg10

Advanced search

Re: [SG10] Checking __has_include on its own is not sufficient

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Thu, 9 Feb 2017 23:55:16 +0000
On 9 February 2017 at 23:25, Jens Maurer <Jens.Maurer_at_[hidden]> wrote:
> On 02/09/2017 11:59 PM, Jonathan Wakely wrote:
>> It's become apparent that the feature-test recommendations for
>> features such as std::string_view, std::variant and std::optional are
>> not sufficient.
>>
>> SD-6 says that to check for std::variant you should use
>> __has_include(<variant>).
>
> My gut reaction to this issue is
> "can't we make __has_include return false if #including
> the header doesn't actually provide the facility"?

Do you mean some way for a header to inform the preprocessor that
although it exists as a file on disk, it should be ignored? That might
be nice, although non-trivial to implement. The preprocessor might
have to open the file, do some basic preprocessing (so that macros
such as __cplusplus and __linux__ and __x86_64__ can be tested in
preprocessor conditions) and check what happens. Either an #error or
some implementation-defined #pragma could make __has_include return
false. That would be a significant change to __has_include, which
currently doesn't need to open the file.

Maybe compilers could deal with it in non-standard ways, so that if
the first line of the header contains some #pragma the __has_include
is false (so the whole file doesn't need to be preprocessed) For
example:

#pragma GCC has_include(__cplusplus >= 201402L)

That could cause __has_include to return the result of the expression
(converted to either 0 or 1, in case somebody uses an expression that
has some other non-zero value).

I originally thought about a __try_include feature, that would attempt
to include the header and if either evaluate to 1 on success, or 0 if
there was an error (either finding the header, or processing it). That
could also be non-trivial to implement though, if for example the
header does:

#define SOME_MACRO 1
#error "blah blah"

Would the macro remain defined after an unsuccessful __try_include ?

If not it might be unpopular with preprocessor implementors. If yes
... it's nasty, but maybe we could say it's unspecified whether any
macros get defined by a failed __try_include. That seems really nasty
though. The error could be in a header included indirectly, after
several other files have been included and liberally defined their own
macros.


> (I would also be happy if "#include <variant>" would simply
> be an error in older modes, although I do agree the gcc
> error message is helpful.)

I thought about proposing a change to the GCC compiler that would
hardcode the __has_include result for standard header names, so it
would be false in C++14 mode, but that might prevent users from
supplying their own <variant> that works in C++14 (technically it's
undefined to give an include file the same name as a standard header,
but in C++14 <variant> isn't a standard header, so it's OK for users
to use).

Adding extra __cpp_lib_xxx macros to SD-6 seemed the simplest
approach, and requires the least work from implementors.

But if people would rather I try to solve this in libstdc++ I can talk
to the GCC folks about the #pragma idea, or something like that (and
then hope that Intel and Clang and others to support it too).

Received on 2017-02-10 00:55:38