General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
|
Translation-unit-local (TU-local) entities are introduced to prevent entities that are supposed to be local (not used in any other translation unit) being exposed and used in other translation units.
An example fromUnderstanding C++ Modules: Part 2 illustrates the problem of not constraining exposures:
// Module unit without TU-local constraintsexport module Foo; import<iostream>; namespace{class LolWatchThis{// internal linkage, cannot be exportedstaticvoid say_hello(){std::cout<<"Hello, everyone!\n";}};} export LolWatchThis lolwut(){// LolWatchThis is exposed as return typereturn LolWatchThis();}
// main.cppimport Foo; int main(){auto evil= lolwut();// 'evil' has type of 'LolWatchThis' decltype(evil)::say_hello();// definition of 'LolWatchThis' is not internal anymore}
Contents |
An entity isTU-local if it is
// TU-local entities with internal linkagenamespace{// all names declared in unnamed namespace have internal linkageint tul_var=1;// TU-local variableint tul_func(){return1;}// TU-local functionstruct tul_type{int mem;};// TU-local (class) type}template<typename T>staticint tul_func_temp(){return1;}// TU-local template // TU-local template specializationtemplate<>staticint tul_func_temp<int>(){return3;}// TU-local specialization // template specialization with TU-local template argumenttemplate<>structstd::hash<tul_type>{// TU-local specializationstd::size_t operator()(const tul_type& t)const{return 4u;}};
This section is incomplete Reason: missing examples of rules #1.2, #2 and #5 |
A value or object isTU-local if either
staticint tul_var=1;// TU-local variablestaticint tul_func(){return1;}// TU-local function int* tul_var_ptr=&tul_var;// TU-local: pointer to TU-local variableint(* tul_func_ptr)()=&tul_func;// TU-local: pointer to TU-local function constexprstaticint tul_const=1;// TU-local variable usable in constant expressionsint tul_arr[]={ tul_const};// TU-local: array of constexpr TU-local objectstruct tul_class{int mem;};tul_class tul_obj{tul_const};// TU-local: has member constexpr TU-local object
A declaration Dnames an entity E if
// lambda namingauto x=[]{};// names decltype(x) // non-function (template) namingint y1=1;// names y1 (id-expression)struct y2{int mem;};y2 y2_obj{1};// names y2 (type-specifier)struct y3{int mem_func();};int y3::mem_func(){return0;}// names y3 (nested-name-specifier)template<typename T>int y4=1;int var= y4<y2>;// names y4 (template-name)template<typename T> concept y5=true;template<typename T>void func(T&&) requires y5<T>;// names y5 (concept-name) // function (template) namingint z1(int arg){std::cout<<"no overload";return0;}int z2(int arg){std::cout<<"overload 1";return1;}int z2(double arg){std::cout<<"overload 2";return2;} int val1= z1(0);// names z1int val2= z2(0);// names z2 ( int z2(int) )
A declaration is anexposure if it either names a TU-local entity, ignoring
or defines a constexpr variable initialized to a TU-local value.
This section is incomplete Reason: missing examples for exposures |
If a (possibly instantiated)declaration of, or adeduction guide for, a non-TU-local entity in amodule interface unit (outside the private-module-fragment, if any) or module partition is an exposure, the program is ill-formed. Such a declaration in any other context is deprecated.
If a declaration that appears in one translation unit names a TU-local entity declared in another translation unit that is not a header unit, the program is ill-formed. A declaration instantiated for a template specialization appears at the point of instantiation of the specialization.
This section is incomplete Reason: missing examples for constraints |
Translation unit #1:
export module A;staticvoid f(){}inlinevoid it(){ f();}// error: is an exposure of fstaticinlinevoid its(){ f();}// OKtemplate<int>void g(){ its();}// OKtemplatevoid g<0>(); decltype(f)*fp;// error: f (though not its type) is TU-localauto&fr= f;// OKconstexprauto&fr2= fr;// error: is an exposure of fconstexprstaticauto fp2= fr;// OKstruct S{void(&ref)();} s{f};// OK: value is TU-localconstexprexternstruct W{ S&s;} wrap{s};// OK: value is not TU-local staticauto x=[]{ f();};// OKauto x2= x;// error: the closure type is TU-localint y=([]{ f();}(),0);// error: the closure type is not TU-localint y2=(x,0);// OK namespace N{struct A{};void adl(A);staticvoid adl(int);}void adl(double); inlinevoid h(auto x){ adl(x);}// OK, but a specialization might be an exposure
Translation unit #2:
module A;void other(){ g<0>();// OK: specialization is explicitly instantiated g<1>();// error: instantiation uses TU-local its h(N::A{});// error: overload set contains TU-local N::adl(int) h(0);// OK: calls adl(double) adl(N::A{});// OK; N::adl(int) not found, calls N::adl(N::A) fr();// OK: calls fconstexprauto ptr= fr;// error: fr is not usable in constant expressions here}
This section is incomplete Reason: examples are too complex, need better arrangement |