[module.reach]

# 10 Modules [[module]](./#module)

## 10.7 Reachability [module.reach]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1006)

A translation unit U is[*necessarily reachable*](#def:reachable,necessarily,translation_unit "10.7 Reachability [module.reach]") from a point P ifU 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 ([[module.import]](module.import "10.3 Import declaration"))[.](#1.sentence-1)

[*Note [1](#note-1)*:

While module interface units are reachable even when they are only
transitively imported via a non-exported import declaration,
namespace-scope names from such module interface units are not found by
name lookup ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#1.sentence-2)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1021)

All translation units that are necessarily reachable are[*reachable*](#def:reachable,translation_unit "10.7 Reachability [module.reach]")[.](#2.sentence-1)

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[.](#2.sentence-2)[87](#footnote-87 "Implementations are therefore not required to prevent the semantic effects of additional translation units involved in the compilation from being observed.")

[*Note [2](#note-2)*:

It is advisable to avoid
depending on the reachability of any additional translation units
in programs intending to be portable[.](#2.sentence-3)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1038)

A declaration D is[*reachable from*](#def:reachable_from,declaration "10.7 Reachability [module.reach]") a point P if

- [(3.1)](#3.1)

P is a non-synthesized point and
  * [(3.1.1)](#3.1.1)

D appears prior to P in the same translation unit, or

  * [(3.1.2)](#3.1.2)

D is not discarded ([[module.global.frag]](module.global.frag "10.4 Global module fragment")),
appears in a translation unit that is
reachable from P,
and
does not appear within a [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]"); or

- [(3.2)](#3.2)

D is the injected declaration
for which P is the corresponding synthesized point[.](#3.sentence-1)

[*Example [1](#example-1)*: class Incomplete;

consteval {int n = nonstatic_data_members_of( define_aggregate(^^Incomplete, {data_member_spec(^^int, {.name="x"})}),
 std::meta::access_context::current()).size();

 Incomplete y; // error: type of y is incomplete}/* P */

The value of n is 1[.](#3.sentence-2)

The member Incomplete​::​x members-of-precedes ([[meta.reflection.member.queries]](meta.reflection.member.queries "21.4.10 Reflection member queries"))
the synthesized point P associated with the injected declaration
produced by the call to define_aggregate[.](#3.sentence-3)

â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1077)

A declaration is [*reachable*](#def:reachable,declaration "10.7 Reachability [module.reach]") if it is reachable from
any point in the instantiation context ([[module.context]](module.context "10.6 Instantiation context"))[.](#4.sentence-1)

[*Note [3](#note-3)*:

Whether a declaration is exported has no bearing on whether it is reachable[.](#4.sentence-2)

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1085)

The accumulated properties of all reachable declarations of
an entity within a context
determine the behavior of the entity within that context[.](#5.sentence-1)

[*Note [4](#note-4)*:

These reachable semantic properties include type completeness,
type definitions, initializers,
default arguments of functions or template declarations, attributes,
names bound, etc[.](#5.sentence-2)

Since default arguments are evaluated in the context of the call expression,
the reachable semantic properties of the corresponding parameter types apply in
that context[.](#5.sentence-3)

[*Example [2](#example-2)*:

Translation unit #1:export module M:A;export struct B;

Translation unit #2:module M:B;struct B {operator int();};

Translation unit #3:module M:C;import :A;
B b1; // error: no reachable definition of struct B

Translation unit #4:export module M;export import :A;import :B;
B b2;export void f(B b = B());

Translation unit #5:import M;
B b3; // error: no reachable definition of struct Bvoid g() { f(); } // error: no reachable definition of struct B â *end example*]

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1132)

[*Note [5](#note-5)*:

Declarations of an entity can be reachable
even where they cannot be found by name lookup[.](#6.sentence-1)

â *end note*]

[*Example [3](#example-3)*:

Translation unit #1:export module A;struct X {};export using Y = X;

Translation unit #2:import A;
Y y; // OK, definition of X is reachable X x; // error: X not visible to unqualified lookup â *end example*]

[87)](#footnote-87)[87)](#footnoteref-87)

Implementations are therefore not required to prevent the semantic
effects of additional translation units involved in the compilation from being
observed[.](#footnote-87.sentence-1)
