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.