[Bug c++/125230] [modules] #include transformed into import

2026-05-09 Thread nshead at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

Nathaniel Shead  changed:

   What|Removed |Added

   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=101126
 CC||nshead at gcc dot gnu.org

--- Comment #11 from Nathaniel Shead  ---
(In reply to Rainer Deyke from comment #8)
> Consensus at [email protected] seems to be that the set of
> "importable headers" is meant to be a finite closed set of
> implementation-provided headers that does not include user-provided headers.
> a.hpp in my example is not supposed to be an "importable header".  Importing
> it should not turn it into an importable header.  Precompiling it should not
> turn it into turn it into an "importable header".  An #include of this
> header be turned into an import.

The actual issue here is PR101126; we don't support precompiled headers with
modules currently.  When you compile a header with modules support enabled, you
are promising the compiler that this is an importable header and are building a
CMI for it.

The default module mapper (for simple command-line usage, not really intended
for proper build systems) then assumes that any header it can see that's been
built is a valid importable header.  If you choose to instead use a custom
module mapper you can indicate which headers are intended to be importable (and
thus should undergo include translation) and which are not.  See also
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Module-Preprocessing.html:

> Include translation converts #include, #include_next and #import directives
> to internal import declarations. Whether a particular directive is translated
> is controlled by the module mapper.

The mapper protocol itself is described in
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Module-Mapper.html and
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1184r2.pdf; see
section 4.9 of the latter to determine whether given headers are meant to be
part of the importable header list or not.

[Bug c++/125230] [modules] #include transformed into import

2026-05-09 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #10 from Jonathan Wakely  ---
I don't think we want the compiler to notice whether a header depends on any
macros, and then mark it for not being translated to import (either
unconditionally or if those macros are defined). 99.999% of headers depend on
macros (of nothing else, the include guard at the very top of the header!) and
many depend on macros which are routinely defined, such as:

#ifdef __linux__

#ifdef __cpp_concepts

We don't want to make a header non-importable just because it uses #ifdef
anywhere in the header.

Recording _which_ macros a header depends on and testing that all of them have
the same definition before doing include translation would work but I'm not
sure how well it would scale.

[Bug c++/125230] [modules] #include transformed into import

2026-05-09 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #9 from Jonathan Wakely  ---
I think GCC's rationale is that you explicitly compiled the header into a
header unit. That part wasn't done silently, you did it. If you tell GCC that
a.hpp can be imported as a header unit, it will assume it can be imported as a
header unit. 

Maybe what we need is an option that turns off include translation, either for
the whole file or for specific headers, so you could still compile a.hpp as a
header unit, but compile b.cpp with -fno-include-translation or
-fno-include-translation=a.hpp

[Bug c++/125230] [modules] #include transformed into import

2026-05-09 Thread rainerd at eldwood dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

Rainer Deyke  changed:

   What|Removed |Added

 Resolution|INVALID |---
 Status|RESOLVED|UNCONFIRMED

--- Comment #8 from Rainer Deyke  ---
Consensus at [email protected] seems to be that the set of
"importable headers" is meant to be a finite closed set of
implementation-provided headers that does not include user-provided headers. 
a.hpp in my example is not supposed to be an "importable header".  Importing it
should not turn it into an importable header.  Precompiling it should not turn
it into turn it into an "importable header".  An #include of this header be
turned into an import.

I concede that the language of the standard is ambiguous, but this is not
"exactly how c++20 modules are supposed to work".

[Bug c++/125230] [modules] #include transformed into import

2026-05-08 Thread rainerd at eldwood dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #7 from Rainer Deyke  ---
(In reply to Jonathan Wakely from comment #6)
> (In reply to Rainer Deyke from comment #5)
> > This is problematic because "importable header" is never defined.  It can
> > reasonably mean "any header" in a compiler that compiles header units on
> > demand, in which case my header-only library cannot work at all.  I believe
> > this is a defect in the standard.
> 
> It's defined in 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)."
> 
> And 16.4.2.3 [headers] p2 says:
> 
> "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."

That just confirms my point: the set of importable headers is
implementation-defined (i.e. not defined by the standard).  It is permitted for
an implementation to treat all headers as importable headers.  Therefore an
implementation is allowed to turn all #includes into imports.  Therefore any
idiom that uses macros to pass information from a C++ source file to a header
is no longer standard-conforming, even if #include is used exclusively.

[Bug c++/125230] [modules] #include transformed into import

2026-05-08 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #6 from Jonathan Wakely  ---
(In reply to Rainer Deyke from comment #5)
> This is problematic because "importable header" is never defined.  It can
> reasonably mean "any header" in a compiler that compiles header units on
> demand, in which case my header-only library cannot work at all.  I believe
> this is a defect in the standard.

It's defined in 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)."

And 16.4.2.3 [headers] p2 says:

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

[Bug c++/125230] [modules] #include transformed into import

2026-05-08 Thread rainerd at eldwood dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #5 from Rainer Deyke  ---
(In reply to Drea Pinski from comment #3)
> https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Modules.html

I don't see any text in the link that suggests that #includes in general are
translated into imports.  The closest I see is this statement:

  But for the standard library in particular this is unnecessary: if a header
unit has been built for the libstdc++ ‘bits/stdc++.h’ header, the compiler will
translate an ‘#include’ of any importable standard library header into an
import of that header unit, speeding up compilation without needing to specify
‘-include’. Note that the ‘bits/stdc++.h’ header unit is also built by the
--compile-std-module option. 

But that statement is specifically about the standard library, and does not
suggest that the same translation happens to other #includes.

> But this is exactly how c++20 modules are supposed to work.

Checking on https://cppreference.com/cpp/preprocessor/include, I see that this
behavior is in fact standard-compliant, but not mandated.  The exact text is
this:

  If the header identified by the header-name (i.e., < h-char-sequence > or "
q-char-sequence ") denotes an importable header, it is implementation-defined
whether the #include preprocessing directive is instead replaced by an import
directive of the form

  import header-name ; new-line 

This is problematic because "importable header" is never defined.  It can
reasonably mean "any header" in a compiler that compiles header units on
demand, in which case my header-only library cannot work at all.  I believe
this is a defect in the standard.

Anyway, given that this is standard-conformant behaviors, it's also not
difficult to work around.

a-indirect.hpp:
  #include "a.hpp"

b.cpp:
  #define A_IMPL
  #include "a.hpp"

c.cpp:
  import "a-indirect.hpp"
c.cpp:

[Bug c++/125230] [modules] #include transformed into import

2026-05-08 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #4 from Drea Pinski  ---


Also read https://isocpp.org/files/papers/D2654R0.html

[Bug c++/125230] [modules] #include transformed into import

2026-05-08 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #3 from Drea Pinski  ---
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Modules.html

Has part of this documented for gcc.

But this is exactly how c++20 modules are supposed to work.

[Bug c++/125230] [modules] #include transformed into import

2026-05-07 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

Drea Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #2 from Drea Pinski  ---
> This may be a clever optimization in some cases, but I believe it is not 
> standard-conforming and it breaks real code.

No it is how c++20 modules work.

[Bug c++/125230] [modules] #include transformed into import

2026-05-07 Thread rainerd at eldwood dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125230

--- Comment #1 from Rainer Deyke  ---
(In reply to Rainer Deyke from comment #0)
> b.ii:
>   # 0 "b.cpp"
>   # 0 ""
>   # 0 ""
>   # 1 "/usr/include/stdc-predef.h" 1 3
>   # 0 "" 2
>   # 1 "b.cpp"

It seems the relevant line was cut off:

import "./a.hpp" [[__translated]];