Skip to content
Merged
Show file tree
Hide file tree
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
173 changes: 169 additions & 4 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,6 @@
the standard or a user-defined library, or (when appropriate) it is
implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor},
\ref{class.dtor}, and \ref{class.copy.assign}).
A definition of an inline function or variable shall be reachable in every
translation unit in which it is odr-used outside of a discarded statement.
\begin{example}
\begin{codeblock}
auto f() {
Expand All @@ -505,6 +503,15 @@
translation unit.
\end{example}

\pnum
A \defn{definition domain} is
a \grammarterm{private-module-fragment} or
the portion of a translation unit
excluding its \grammarterm{private-module-fragment} (if any).
A definition of an inline function or variable shall be reachable
from the end of every definition domain
in which it is odr-used outside of a discarded statement.

\pnum
\indextext{type!incomplete}%
A definition of a class is required to be reachable in every context in which
Expand Down Expand Up @@ -1979,8 +1986,8 @@
f(x); // OK, calls \tcode{R::f} from interface of \tcode{M}
f(x, S::Z()); // error: \tcode{S::f} in module \tcode{M} not considered
// even though \tcode{S} is an associated namespace
apply(x, S::Z()); // OK, \tcode{S::f} is visible in instantiation context, and
// \tcode{R::g} is visible even though it has internal linkage
apply(x, S::Z()); // error: \tcode{S::f} is visible in instantiation context, but
// \tcode{R::g} has internal linkage and cannot be used outside TU \#2
}
\end{codeblocktu}
\end{example}
Expand Down Expand Up @@ -2876,6 +2883,164 @@
\end{note}
\indextext{linkage|)}

\pnum
A declaration $D$ \defnx{names}{name} an entity $E$ if
\begin{itemize}
\item
$D$ contains a \grammarterm{lambda-expression} whose closure type is $E$,
\item
$E$ is not a function or function template and $D$ contains an
\grammarterm{id-expression},
\grammarterm{type-specifier},
\grammarterm{nested-name-specifier},
\grammarterm{template-name}, or
\grammarterm{concept-name}
denoting $E$, or
\item
$E$ is a function or function template and
$D$ contains an expression that names $E$\iref{basic.def.odr} or
an \grammarterm{id-expression}
that refers to a set of overloads that contains $E$.
\begin{note}
Non-dependent names in an instantiated declaration
do not refer to a set of overloads\iref{temp.nondep}.
\end{note}
\end{itemize}

\pnum
A declaration is an \defn{exposure}
if it either names a TU-local entity (defined below), ignoring
\begin{itemize}
\item
the \grammarterm{function-body}
for a non-inline function or function template
(but not the deduced return type
for a (possibly instantiated) definition of a function
with a declared return type that uses a placeholder type\iref{dcl.spec.auto}),
\item
the \grammarterm{initializer}
for a variable or variable template (but not the variable's type),
\item
friend declarations in a class definition, and
\item
any reference to a non-volatile const object or reference
with internal or no linkage initialized with a constant expression
that is not an odr-use\iref{basic.def.odr},
\end{itemize}
or defines a constexpr variable initialized to a TU-local value (defined below).
\begin{note}
An inline function template can be an exposure even though
explicit specializations of it might be usable in other translation units.
\end{note}

\pnum
An entity is \defnx{TU-local}{TU-local!entity} if it is
\begin{itemize}
\item
a type, function, variable, or template that
\begin{itemize}
\item
has a name with internal linkage, or
\item
does not have a name with linkage and is declared,
or introduced by a \grammarterm{lambda-expression},
within the definition of a TU-local entity,
\end{itemize}
\item
a type with no name that is defined outside a
\grammarterm{class-specifier},
function body, or
\grammarterm{initializer}
or is introduced by a \grammarterm{defining-type-specifier}
that is used to declare only TU-local entities,
\item
a specialization of a TU-local template,
\item
a specialization of a template with any TU-local template argument, or
\item
a specialization of a template
whose (possibly instantiated) declaration is an exposure.
\begin{note}
The specialization might have been implicitly or explicitly instantiated.
\end{note}
\end{itemize}

\pnum
A value or object is \defnx{TU-local}{TU-local!value or object} if either
\begin{itemize}
\item
it is, or is a pointer to,
a TU-local function or the object associated with a TU-local variable,
\item
it is an object of class or array type and
any of its subobjects or
any of the objects or functions
to which its non-static data members of reference type refer
is TU-local and is usable in constant expressions.
\end{itemize}

\pnum
If a (possibly instantiated) declaration of, or a deduction guide for,
a non-TU-local entity in a module interface unit
(outside the \grammarterm{private-module-fragment}, if any) or
module partition\iref{module.unit} is an exposure,
the program is ill-formed.
Such a declaration in any other context is deprecated\iref{depr.local}.

\pnum
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\iref{temp.spec}
appears at the point of instantiation of the specialization\iref{temp.point}.

\pnum
\begin{example}
\begin{codeblocktu}{Translation unit \#1}
export module A;
static void f() {}
inline void it() { f(); } // error: is an exposure of \tcode{f}
static inline void its() { f(); } // OK
template<int> void g() { its(); } // OK
template void g<0>();

decltype(f) *fp; // error: \tcode{f} (though not its type) is TU-local
auto &fr = f; // OK
constexpr auto &fr2 = fr; // error: is an exposure of \tcode{f}
constexpr static auto fp2 = fr; // OK

struct S { void (&ref)(); } s{f}; // OK, value is TU-local
constexpr extern struct W { S &s; } wrap{s}; // OK, value is not TU-local

static auto x = []{f();}; // OK
auto x2 = x; // error: the closure type is TU-local
int y = ([]{f();}(),0); // error: the closure type is not TU-local
int y2 = (x,0); // OK

namespace N {
struct A {};
void adl(A);
static void adl(int);
}
void adl(double);

inline void h(auto x) { adl(x); } // OK, but a specialization might be an exposure
\end{codeblocktu}
\begin{codeblocktu}{Translation unit \#2}
module A;
void other() {
g<0>(); // OK, specialization is explicitly instantiated
g<1>(); // error: instantiation uses TU-local \tcode{its}
h(N::A{}); // error: overload set contains TU-local \tcode{N::adl(int)}
h(0); // OK, calls \tcode{adl(double)}
adl(N::A{}); // OK; \tcode{N::adl(int)} not found, calls \tcode{N::adl(N::A)}
fr(); // OK, calls \tcode{f}
constexpr auto ptr = fr; // error: \tcode{fr} is not usable in constant expressions here
}
\end{codeblocktu}
\end{example}

\rSec1[basic.memobj]{Memory and objects}

\rSec2[intro.memory]{Memory model}
Expand Down
42 changes: 19 additions & 23 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,8 @@
still be respected.
\begin{note}
The \tcode{inline} keyword has no effect on the linkage of a function.
In certain cases, an inline function cannot use names with internal linkage;
see~\ref{basic.link}.
\end{note}

\pnum
Expand All @@ -1066,27 +1068,24 @@
been declared inline.

\pnum
If an inline function or variable
is odr-used in a translation unit,
a definition of it shall be reachable from the end of that translation unit,
and it shall have exactly the same definition
in every such translation unit\iref{basic.def.odr}.
\begin{note}
A call to the inline function or a use of the inline variable may be encountered before its definition
appears in the translation unit.
\end{note}
If a definition of a function or variable is reachable
at the point of its
first declaration as inline, the program is ill-formed. If a function or variable
with external or module linkage
is declared inline in one translation unit,
there shall be a reachable inline declaration
in all translation units in which it is declared;
is declared inline in one definition domain,
an inline declaration of it shall be reachable
from the end of every definition domain in which it is declared;
no diagnostic is required.
\begin{note}
A call to an inline function or a use of an inline variable may be encountered
before its definition becomes reachable in a translation unit.
\end{note}

\pnum
\begin{note}
An inline function or variable
with external or module linkage
shall have the same address in all translation units.
\begin{note}
has the same address in all translation units.
A \tcode{static} local variable in an inline
function with external or module linkage
always refers to the same object.
Expand All @@ -1096,14 +1095,11 @@
\end{note}

\pnum
An exported inline function or variable
shall be defined in the translation unit
containing its exported declaration,
outside the \grammarterm{private-module-fragment} (if any).
If an inline function or variable that is attached to a named module
is declared in a definition domain,
it shall be defined in that domain.
\begin{note}
There is no restriction on the linkage (or absence thereof)
of entities that the function body of an exported inline function
can reference. A constexpr function\iref{dcl.constexpr} is implicitly inline.
A constexpr function\iref{dcl.constexpr} is implicitly inline.
In the global module, a function defined within a class definition
is implicitly inline~(\ref{class.mfct}, \ref{class.friend}).
\end{note}
Expand Down Expand Up @@ -1788,8 +1784,8 @@
containing its exported declaration,
outside the \grammarterm{private-module-fragment} (if any).
\begin{note}
There is no restriction on the linkage of
the deduced return type.
The deduced return type cannot have
a name with internal linkage\iref{basic.link}.
\end{note}

\pnum
Expand Down
17 changes: 13 additions & 4 deletions source/expressions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6852,10 +6852,19 @@
\end{itemize}

\pnum
A variable is \defn{usable in constant expressions} after
its initializing declaration is encountered if it is a constexpr variable, or
it is a constant-initialized variable
of reference type or of const-qualified integral or enumeration type.
A variable is \defn{potentially-constant} if
it is constexpr or
it has reference or const-qualified integral or enumeration type.

\pnum
A constant-initialized potentially-constant variable is
\defn{usable in constant expressions} at a point $P$ if
its initializing declaration $D$ is reachable from $P$ and
\begin{itemize}
\item it is constexpr,
\item it is not initialized to a TU-local value, or
\item $P$ is in the same translation unit as $D$.
\end{itemize}
An object or reference is \defn{usable in constant expressions} if it is
\begin{itemize}
\item a variable that is usable in constant expressions, or
Expand Down
20 changes: 20 additions & 0 deletions source/future.tex
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,26 @@
\end{codeblock}
\end{example}

\rSec1[depr.local]{Non-local use of TU-local entities}

\pnum
A declaration of a non-TU-local entity that is an exposure\iref{basic.link}
is deprecated.
\begin{note}
Such a declaration in an importable module unit is ill-formed.
\end{note}
\begin{example}
\begin{codeblock}
namespace {
struct A {
void f() {}
};
}
A h(); // deprecated: not internal linkage
inline void g() {A().f();} // deprecated: inline and not internal linkage
\end{codeblock}
\end{example}

\rSec1[depr.impldec]{Implicit declaration of copy functions}

\pnum
Expand Down
42 changes: 32 additions & 10 deletions source/modules.tex
Original file line number Diff line number Diff line change
Expand Up @@ -477,26 +477,41 @@
set of headers that
includes all importable \Cpp{} library headers\iref{headers}.
\tcode{H} shall identify an importable header.
Two
\grammarterm{module-import-declaration}{s}
import the same header unit if and only if
their \grammarterm{header-name}{s} identify the same
header or source file\iref{cpp.include}.
Given two such \grammarterm{module-import-declaration}{s}:
\begin{itemize}
\item
if their \grammarterm{header-name}{s} identify
different headers or source files\iref{cpp.include},
they import distinct header units;
\item
otherwise, if they appear in the same translation unit,
they import the same header unit;
\item
otherwise, it is unspecified whether they import the same header unit.
\begin{note}
It is therefore possible that multiple copies exist of entities
declared with internal linkage in an importable header.
\end{note}
\end{itemize}
\begin{note}
A \grammarterm{module-import-declaration} nominating
a \grammarterm{header-name} is also recognized by the
preprocessor, and results in macros defined at the
end of phase 4 of translation of the header unit
being made visible as described in \ref{cpp.import}.
\end{note}

\pnum
A declaration of a name with internal linkage is
permitted within a header unit despite all
declarations being implicitly exported\iref{module.interface}.
If such a declaration declares an entity
that is odr-used outside the
header unit, or by a template
instantiation whose point of instantiation is outside
the header unit, the program is ill-formed.
\begin{note}
A definition that appears in multiple translation units
cannot in general refer to such names\iref{basic.def.odr}.
\end{note}
A header unit shall not contain
a definition of a non-inline function or variable
whose name has external linkage.

\pnum
When a \grammarterm{module-import-declaration} imports
Expand Down Expand Up @@ -803,6 +818,13 @@
an exported function with a placeholder return type
is required\iref{dcl.spec.auto},

\item
whether a declaration is required not to be an exposure\iref{basic.link},

\item
where definitions for inline functions and templates
must appear~(\ref{basic.def.odr}, \ref{temp.pre}),

\item
the instantiation contexts of templates
instantiated before it\iref{module.context}, and
Expand Down
Loading