https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79433
Marc Mutz <marc.mutz at kdab dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |UNCONFIRMED Resolution|INVALID |--- --- Comment #9 from Marc Mutz <marc.mutz at kdab dot com> --- __has_include these days is defined by SD-6, and while not spelled out in normative text, the intent is very much for it to be able to detect presence of a header for inclusion. Quoting from https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations: This demonstrates a way to use a library optional facility only if it is available. #ifdef __has_include # if __has_include(<optional>) # include <optional> # define have_optional 1 # elif __has_include(<experimental/optional>) # include <experimental/optional> # define have_optional 1 # define experimental_optional # else # define have_optional 0 # endif #endif So, IMHO, you do have a bug here, because this example does not work as intended by its defining norm. Absent any proof to the contrary, I believe that in order to conform to SD-6, you have to move such headers under a c++1{1,4,z}/ subdir which only gets added to the include path if the resp. -std is in effect. This will make the example from SD-6 work, as well as enabling the use-case Jonathan mentioned in the IRC log. Note that removing the #error from the header files, so they can at least be included, if present, and a corresponding __cpp_lib macro can be evaluated is still not conforming to SD-6, since the example assumes that availability of the header implies usability without further checks, making __cpp_lib macros useful for versioning