> As you outline, because header units leak macros into their consuming context, they're effectively undecidable.
Decidability does not matter. Practicality like cyclic dependency detection matters, and practicality here is at least as achievable as traditional header files, which is very much indeed achievable.
I am not sure what you mean here by "undecidable". Computability-theoretically speaking, CPP is indeed undecidable. Although I don't know if header units are undecidable. But all math aside, like elaborated above, decidability does not matter.
If you mean "not lexically locally immediately computed", then yes.
> Your A/B/C demonstrates the loop. We can't scan accurately scan C without knowing A, but we don't know that A is required without scanning C. The only way to resolve this is something like the module mapper protocol, build-system-in-the-loop with the compiler. However, that risks deadlocks.
I do not understand how any of the examples demonstrate that situation which I also don't understand at all and how a GCC module mapper is critical in that. Can you demonstrate?
Far as I see, the preprocessor state does cause problems, but none of them can't be solved with a reasonable amount of effort and minimal external impact. This whole RFC points out potential and existing solutions and how we can better utilize them.
> Outside a change to the standard, nothing will meaningfully move here. Trying to standardize tooling without the compilers agreeing on a model is a fool's errand. The compilers won't standardize a model without coherence from the standard.
>
> All this to say: this needs to go back to SG15 and WG21 to fix this bug in header units prior to trying to do anything downstream. If all the compilers had agreed on a single coherent model I might think differently, but again you illustrate that they have not.
Compilers fully agree on everything, which has and causes no issue at all. Scanners' behaviors and the backing philosophies differ, which is out of the scope of the C++ language IS and thus not requiring any modification to it.
> Aside from all that, the only thing we want from header units is to treat them like interface units. Scan once, get the direct imports, done. No need to chase imports, so no question about whether the report is transitive or non-transitive. That model has proven remarkably durable. The scanner format described by P1689 anticipated this to be the mechanism header units used.
The whole point of header units is the partial preprocessor awareness, which mandates transitive scanning and `import` chasing. However, scanning and reporting are very much orthogonal in this specific problem. You can scan transitively and report non-transitively. The only requirement is that in the final summary, the `import` layer information is reserved.
Layered reporting is mandated due to the build requirement of CMIs, which is universal between named modules and header units. Such layering can be achieved by non-transitive reporting (like named modules already do) or non-trivial transitive reporting, regardless of whether you're dealing with named modules or header units. Everything applies to both, so I don't understand how "treat them like interface units" clarifies or avoids any problem.
> I would much rather see header units come to P1689 than mutate that trivial format to meet the broken mechanism of header units.
Header units don't need to "come to P1689". They already are there. They lack certain additional components and that's all.