<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/60079>60079</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [C++20][Modules] Standard header units impractical since ban of non-inline external definitions
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          kaimfrai
      </td>
    </tr>
</table>

<pre>
    Since non-inline external definitions in header units were disallowed in [commit/335668b](https://github.com/llvm/llvm-project/commit/335668b116439d13c7555616e126acdc608ce59e), using standard header units has become impractical.
In particular, the example given at https://clang.llvm.org/docs/StandardCPlusPlusModules.html#header-units
```clang++ -std=c++20 -xc++-system-header --precompile iostream -o iostream.pcm```
no longer compiles with current Clang 16 (tried libc++ and libstdc++) while it did work before.

Errors include but are not limited to:
### libstdc++
```
include/c++/12/new:206:8: error: non-inline external definitions are not permitted in C++ header units
  void launder(volatile void*) = delete;
```
```
include/c++/12/type_traits:2125:27: error: non-inline external definitions are not permitted in C++ header units
 static const size_t _S_alignment = 0;
```

### libc++
```
 include/c++/v1/__type_traits/aligned_union.h:29:25: error: non-inline external definitions are not permitted in C++ header units
    static const size_t value = _I0;
```
```
include/c++/v1/__functional/reference_wrapper.h:100:27: error: non-inline external definitions are not permitted in C++ header units
template <class _Tp> void ref(const _Tp&&) = delete;
```

Unfortunately, this issue isn't limited to libstdc++ and libc++. Not only do other headers often include standard headers, but it's entirely resonable to have = delete; in header files. They are therefore also unusable as header units. Transitioning from headers to header units is thus limited to a small subset of headers, while Clang 15 allowed many more. While I think it's the correct default to error out in these cases, I would appreciate an explicit flag that skips over this rule, at least until P1502R1 (Standard library Header Units) or P2465R3 (std module) are implemented. For example:

```clang++ -std=c++20 -xc++-system-header -fallow-non-inline-external-definitions-in-header-units --precompile iostream -o iostream.pcm```

Without such a flag I would find it very hard to make use of standard header units as they are implemented right now.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vk2P2zgS_TX0pWBDolqyffChP2JsH3YRpBPkaJTJksVtihTIkh3vr19Qkjvuns4kM5gAsqxPVr1XpfcKYzQHR7QR5Z0oH2bYc-PD5hlNWwc0s73X582TcYrAeTc3zhpHQN-YgkMLmmrjDBvvIhgHDaGmAL0zHOFEgUCbiNb6E-l0X5R3yretYSG3RVFW1WovygchVw1zF0VxK-RWyO3BcNPvF8q3Qm6tPV7-5l3w_yWV3n67TJ5XN8Va54ValmVZ5RXlskKlVZWtFJVrEnIt5D300bgDREanMejXCTcYYU_KtwSm7QIqNgrtQmQPIrt9dNBhYKN6iyGtxE3iAdvOEhzMkRwgw2scyqI7LFLmCx8OQm61V1HI7dMU_v6j7WP6_dvr3lJcNNxaIYsxq_mQ1RhdVNm4DUsKeSfkHcwja1E8qPFUZjD_Nh3P4zkytfMJ3nzehYSrM5bA-MiBsIW5fzledKp9CTFGdB6sdwcKML0Y4WS4AdWHQI7hPiUCeQVCrjgY0mDNfgoP6IbTyHq6IuQaTs0QnkEbDScfnmFPtQ80ETzuP4TgQ-olZXtNsO8ZMKTeY7CmNUwa2CeCx3dkMW5vor3mbDydlkxlueS0zaWQW0cnUdzKrBLF7UoUt0Aph3Tws46_ZNZRaA3z2OP3EwfXrTVmAHD0RoPF3mkKQq6O3iInUtJ1IW8TS6J4AE2WmETxPpBfxcXnjnYcMMUvbmUuy_S3_K0IIyMbBcq7yBDN_2jHsHvaoTUH16a2SfCyHyL7Y1H_rKLwHvRjLuR2t7sGL7dDfNK73hnvFk3iYZ125e8tN7zLxxFtTwMRu8cfU_HzIk9I696plB9aIbeBagrkFO1OAbuOwgA2z7LfXnqmtrPICdi9shgj7D53ovgw9nygWsjVSEO6Lqth-6V2H_ZfXO0D9w6Z7HmUXxPBxNgTmOiEXF4LxGs5uMjRdLqA_3gG7-wZtAfPDYUJTwRfM7kX9XljEzHFTYqUjGcZgRybQPYMgaJ3uLeUQjd4pNewrpyxTkK6gM8NnQeCU_BBBAFt9NC7Pg7rYHxF8QI-B3RxqEzyrzr49iXnFPPaxkwEbvp4TQdCbNFaiP0-EoOvrxGNujzpeQkXu27RnaFN-gxfhyceE-fu-YI--Z_yIZDi1DfYW06hhv4Cn1hy6ZlIoDDSEOkRTr63GrBLfmRSt6AD-tZZowxDbfEA3CBDfDZdBH-kMNY59JbSAshgCSND79hY-JiXmfyUJwu6WGqqc8Bwhn-NlHwZOlSuwQf4KG-q8lORHo-soR1MN91LlTDJyJNEkV7A1oeLt3_3mn_CiOuB3fn3b29--fbmV9_e3Lj59Qzwtwx83H813KRixF41gCPFlzLUxunkx0cKZ2gSeeyhxWeCPlJqkvfHJBxqf37LGgRzaBicP02GPtObQq-LNc5ok1fLYrVaL8vVrNms9upmmZeFqtRymRPher3KSlrqvM5vNK5nZiMzWWR5XuVLKYvVolip_U1W1xnpQiFKcZNRi8a-zFazQQk2VZYt1zOLe7JxmGildHQaZUJImQbcsBkmyX1_iOImsyZy_L4KG7bDKHx_KWUaT8u7aT4T5QM8vcvJ1bwIcZiW9-gShT9R2Vkf7OYvD78DnuRrA97_BwAA__9UKM2P">