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).
> 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