[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)