Skip to content

[Doc] [C++20] [Modules] Clarify the reachability of internal partition units #102572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions clang/docs/StandardCPlusPlusModules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,58 @@ parsing their headers, those should be included after the import. If the
imported modules don't provide such a header, one can be made manually for
improved compile time performance.

Reachability of internal partition units
----------------------------------------

The internal partition units are sometimes called implementation partition units in other documentation.
However, the name may be confusing since implementation partition units are not implementation
units.

According to `[module.reach]p1 <https://eel.is/c++draft/module.reach#1>`_ and
`[module.reach]p2 <https://eel.is/c++draft/module.reach#2>`_ (from N4986):

A translation unit U is necessarily reachable from a point P if U is a module
interface unit on which the translation unit containing P has an interface
dependency, or the translation unit containing P imports U, in either case
prior to P.

All translation units that are necessarily reachable are reachable. Additional
translation units on which the point within the program has an interface
dependency may be considered reachable, but it is unspecified which are and
under what circumstances.

For example,

.. code-block:: c++

// a.cpp
import B;
int main()
{
g<void>();
}

// b.cppm
export module B;
import :C;
export template <typename T> inline void g() noexcept
{
return f<T>();
}

// c.cppm
module B:C;
template<typename> inline void f() noexcept {}

The internal partition unit ``c.cppm`` is not necessarily reachable by
``a.cpp`` because ``c.cppm`` is not a module interface unit and ``a.cpp``
doesn't import ``c.cppm``. This leaves it up to the compiler to decide if
``c.cppm`` is reachable by ``a.cpp`` or not. Clang's behavior is that
indirectly imported internal partition units are not reachable.

The suggested approach for using an internal partition unit in Clang is
to only import them in the implementation unit.

Known Issues
------------

Expand Down
Loading