C++ Logo


Advanced search

Re: P2898R0: Importable Headers are Not Universally Implementable

From: Mathias Stearn <redbeard0531_at_[hidden]>
Date: Fri, 26 May 2023 15:28:44 +0200
On Fri, May 26, 2023 at 2:53 PM Ben Boeckel <ben.boeckel_at_[hidden]> wrote:

> On Fri, May 26, 2023 at 13:55:43 +0200, Mathias Stearn via SG15 wrote:
> > Given the note in http://eel.is/c++draft/cpp.import#5 applying to the
> > definition of the term "macro definition", we should probably change the
> > CWG2732 note to say something like "macro definitions and predefined
> > macros". While -D predefined macros are somewhat outside the scope of the
> > standard, and the standard has no concept of a build using different
> values
> > for the standardized predefined macros for different TUs (which is
> > unfortunately common practice), I think we should be clear (in a note)
> > that the predefined macros used for a header unit are those used when
> > compiling *its* TU, not the importer's.
> What about other flags that affect preprocessor state? This includes
> things like `-m` flags and `-f` flags that can affect things like
> `__x86_64__` definitions and `__has_builtin` queries.
> If we can get into the standard that a TU's flags that get used for a
> BMI are "trusted" (in some sense) it would seem to me that we'd be a lot
> closer to being able to build fewer BMIs for a given header unit. I
> suspect that such a thing is signing up implementations for a lot more
> work though.

I _think_ the current normative wording already says that is the case*.
However, given that that doesn't match the current compiler behavior that
doesn't really help much. I will admit that my opinion of header units
being useful, helpful, and practical does rely on that bit of the wording,
and that it doesn't match compiler reality today. I would be much happier
seeing compilers move to standard-mandated behavior, rather than changing
the standard to match current behavior. Of course neither happening is
worse, since a standard that isn't followed is worthless. But I assume
since people from the 3 main compiler vendors were heavily involved in the
wording, they believe it isn't too much work for their implementations to
comply with it.

* there is a much thornier question of mixing -std= flags. The standard is
by necessity silent on that because normatively there is only one active
standard. However, in practice implementations support both a) picking a
standard other than the latest one, and b) mixing files compiled with
different standards into the same program image (even if this is an
ODR-violating Bad Idea). I have no idea what it means to import the C++23
<vector> (eg) into a TU compiled for C++20, or vice versa. Both directions
seem likely to be nonsensical since the C++N <vector> is likely to use
language features that don't exist in C++(N-3), and a C++23 TU is likely to
depend on vector features that aren't present in C++20. I think that at
least for standard headers, they need to have different BMIs for different
C++ versions. For non-std headers, I could imagine allowing cross-version
usages, but there are a lot of unknowns, including what to do if they
transitively import std headers. For C++20 modules it was easy because
there could only be one (non-expirimental) -std= with modules, however,
with C++23 that would no longer be the case. I had hoped that we would have
figured this out in the 3 years between 20 and 23, but clearly that hasn't
happened. And FWIW, I think the new std module has this same
problem, although it can kick the can down the road for 3 more years.

Received on 2023-05-26 13:28:59