C++ Logo

std-proposals

Advanced search

Re: [std-proposals] #includes turning into imports breaks existing usage

From: Rainer Deyke <rainerd_at_[hidden]>
Date: Fri, 8 May 2026 21:02:09 +0200
On 5/8/26 17:48, Andre Kostur wrote:
> On Fri, May 8, 2026 at 8:35 AM Rainer Deyke via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>>
>> Here is my understanding of the current situation:
>>
>> The set of importable headers is implementation-defined, and can
>> potentially include all headers.
>
> Not sure what you mean about "potentially include all headers". As
> far as I know, the Standard does not claim that any arbitrary header
> is importable, precisely because of things like dependencies on
> macros. And note that if it's implementation-defined, then it is
> highly unlikely that the implementation will claim that any arbitrary
> user-defined header file is importable. (Where the examples you give
> below are all user-defined headers)

Implementation-defined means just that. I don't think the standard
imposes any restriction on how the implementation defines importable.

>> The compiler may, at its discretion, turn all #includes of importable
>> headers into imports. Which, again, is potentially all headers.
>
> Not sure where that's stated, but do note the phrase "importable
> header". I would suggest that headers that depend on macros are not
> importable.

That's not how the standard defines "importable header".

10.3 [module.import] paragraph 5:

"An importable header is a member of an implementation-defined set of
headers that includes all importable C++ library headers (16.4.2.3)."

16.4.2.3 [headers] p2:

"The headers listed in Table 24, or, for a freestanding implementation,
the subset of such headers that are provided by the implementation, are
collectively known as the importable C ++ library headers."

I have those two references ready because I was just given them in gcc's
Bugzilla, where I was told that gcc's interpretation of "importable
header" was correct because, even though it includes macro-dependent
headers.

gcc does not seem to look at the contents of headers to determine if
they are importable. Determining if a header depends on external macros
just by looking at it would be very hard, since the behavior of almost
any header, including all headers in the standard library, can be
changed by defining the right macros. Instead, gcc looks if the header
has been precompiled, which has nothing to do with its content.

You might claim it's my own fault for precompiling headers that are not,
in fact, importable. To which my reply is fourfold:

1. The set of importable headers is, again, implementation-defined.
There is nothing in the standard that forbids gcc from considering these
headers as importable.

2. In the absence of documentation to the contrary, I put to you that
the fact that gcc precompiles these headers without error message and
then converts #includes to these headers into imports, suggests that gcc
does, in fact, consider these headers importable.

3. The requirement to precompile importable headers is an implementation
detail of gcc. A different compiler might choose to compile imported
headers as it encounters them, with no separate precompile step. If it
is legal for gcc to treat a precompiled header as an importable header,
then it is also legal for a different compiler to treat the same header
as an importable header without a precompile step.

4. If I can't determine if a given header is importable for a given
compiler, much less in general, what can I do? I can't even say forget
importable headers and go back to #include, because, again, #includes
can silently change into imports in a way that changes their behavior.
That precompiled header that is breaking my builds might not even be
from my current build.


I suppose you can be argue that the intention of the "importable header"
set is to include only the standard library and other
implementation-provided headers, with user-defined headers categorically
excluded. In that case the concept of importable header is mostly
obsolete except for the few macros in the standard library that can't be
accessed from the std module. Also, gcc is then going against the
spirit (but not the letter) of the standard by converting #includes to
precompiled user-defined headers into imports.


-- 
Rainer Deyke - rainerd_at_[hidden]

Received on 2026-05-08 19:02:20