C++ Logo

std-discussion

Advanced search

On some unspecified bits of P1689R5

From: vspefs <vspefs_at_[hidden]>
Date: Fri, 30 Jan 2026 18:06:24 +0000
I'd like to raise two unresolved questions about C++ header unit scanning in P1689R5 that are currently blocking implementation work.

It's about how we scan header units that `import` each other. For example:

```c++
// a.hh
import "b.hh";
```

```c++
// b.hh
```

```c++
// c.cc
import "a.hh";
```

Now what do we get if we scan `c.cc`? We can expect it 1) requires `a.hh` 2) requires both `a.hh` and `b.hh`.

Rationale:

For 1: A header unit can basically be considered a module in the build DAG. We naturally expect the dependency scanning facility does so as well. This means the `xxx` in `import xxx` is treated as an opaque import, and dependency scanning stops there. We unify header unit and module logic.
For 2: A header unit is, after all, a header. So,
- A header is resolved in place by the compiler the moment it sees the driver options. A header unit should behave similarly, resolving everything as early as possible.
- At C++ level, importing a header unit is described to be very similar to including it. So by `import "a.hh";`, here it should behave as if `c.cc` contained `import "b.hh";` directly. Then it would only make sense to also add `b.hh` to the output.

So both have reasons, and both are operable for module tooling. We just need a clear specification. Currently, `clang-scan-deps` doesn't support header units, `g++ -M -Mmodules` aborts if the CMI of imported header units can't be found, which makes it pointless because we scan to know what CMI it requires, and MSVC does the 2nd option, and aborts if the header units can't be found in the way that included header files are found.

It leads to the 2nd question. As the 1st question is about the scanning strategy, the 2nd question is about the scanning correctness: should `import "header"` be modeled as a fancy `#include` or just another `import module`? If

- It's more like `#include`:
  GCC does the wrong thing by requiring a CMI to know a dependency. We should do the MSVC thing, resolving every level of header units with the traditional `-I` driver options at the time of preprocessing a source. If we can't, we abort.

- It's more like `import module;`:
  MSVC does the wrong thing by using `-I` to resolve header units. Header units can and should only be found like modules, which means the module mapping mechanics of the compilers (module mapper for GCC, `/ifcSearchDir` and `/reference` for MSVC, etc.).
  It would also mean `c.cc` won't have to know where `b.hh` is.

The 2 questions are of importance if we want to have a robust, universal support for dependency scanning. I'd welcome guidance on which direction the committee intends, or whether this should be addressed in a future revision.

Received on 2026-01-30 18:06:34