Skip to content
Open
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
78 changes: 41 additions & 37 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@
\pnum
Every program shall contain at least one definition of every
function or variable that is odr-used in that program
outside of a discarded statement\iref{stmt.if}; no diagnostic required.
outside of a discarded statement\iref{stmt.if}; no diagnostic required\ifndrdef{basic.def.odr.minimum.one.def}.
The definition can appear explicitly in the program, it can be found in
the standard or a user-defined library, or (when appropriate) it is
implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor},
Expand Down Expand Up @@ -762,21 +762,23 @@
that definition shall be an injected declaration
having the same characteristic sequence as $X$;
a diagnostic is required only if \tcode{D} is attached to a named module and
a prior definition is reachable at the point where a later definition occurs.
a prior definition is reachable
at the point where a later definition occurs\ifndrdef{basic.def.odr.injected.match}.

\pnum
For any other definable item \tcode{D} with definitions in multiple translation units,
\begin{itemize}
\item
if \tcode{D} is a non-inline non-templated function or variable, or
if \tcode{D} is a non-inline non-templated function or variable\ifndrdef{basic.def.odr.maximum.one.def}, or
\item
if the definitions in different translation units
do not satisfy the following requirements,
do not satisfy the following requirements\ifndrdef{basic.def.odr.definition.matches},
\end{itemize}
the program is ill-formed;
a diagnostic is required only
if the definable item is attached to a named module and
a prior definition is reachable at the point where a later definition occurs.
a prior definition is reachable
at the point where a later definition occurs.
Given such an item,
for all definitions of \tcode{D}, or,
if \tcode{D} is an unnamed enumeration,
Expand Down Expand Up @@ -957,7 +959,7 @@
reachable unnamed enumeration definition in the same scope
that have the same first enumerator name and
do not have typedef names for linkage purposes\iref{dcl.enum},
those unnamed enumeration types shall be the same; no diagnostic required.
those unnamed enumeration types shall be the same; no diagnostic required\ifndrdef{basic.def.odr.unnamed.enum.same.type}.
\indextext{one-definition rule|)}

\rSec1[basic.scope]{Scope}%
Expand Down Expand Up @@ -1838,7 +1840,7 @@
If it is an invalid set, the program is ill-formed.
If it differs from the result of a search in $T$ for $M$
in a complete-class context\iref{class.mem} of $T$,
the program is ill-formed, no diagnostic required.
the program is ill-formed, no diagnostic required\ifndrdef{class.member.lookup.name.refers.diff.decl}.
\begin{example}
\begin{codeblock}
struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \}
Expand Down Expand Up @@ -3166,7 +3168,8 @@
declarations for an array
object can specify array types that differ by the presence or absence of
a major array bound\iref{dcl.array}.
No diagnostic is required if neither declaration is reachable from the other.
No diagnostic is required
if neither declaration is reachable from the other\ifndrdef{basic.link.consistent.types}.
\begin{example}
\begin{codeblock}
int f(int x, int x); // error: different entities for \tcode{x}
Expand Down Expand Up @@ -3768,7 +3771,7 @@
zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type}
in its specified region of storage
if doing so would result in the program having defined behavior.
If no such set of objects would give the program defined behavior,
If no such set of objects would give the program defined behavior\ubdef{intro.object.implicit.create},
the behavior of the program is undefined.
If multiple such sets of objects would give the program defined behavior,
it is unspecified which such set of objects is created.
Expand All @@ -3786,7 +3789,7 @@
and produce a pointer value that points to that object,
if that value would result in the program having defined behavior.
If no such pointer value would give the program defined behavior,
the behavior of the program is undefined.
the behavior of the program is undefined\ubdef{intro.object.implicit.pointer}.
If multiple such pointer values would give the program defined behavior,
it is unspecified which such pointer value is produced.

Expand Down Expand Up @@ -3840,7 +3843,7 @@
using the \grammarterm{alignment-specifier}\iref{dcl.align}.
Attempting to create an object\iref{intro.object} in storage that
does not meet the alignment requirements of the object's type
is undefined behavior.
is undefined behavior\ubdef{basic.align.object.alignment}.

\pnum
A \defnadj{fundamental}{alignment} is represented by an alignment
Expand Down Expand Up @@ -4029,19 +4032,20 @@
if the pointer were of type \tcode{\keyword{void}*} is
well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in
limited ways, as described below. The
program has undefined behavior if
program has undefined behavior if:
\begin{itemize}
\item
the pointer is used as the operand of a \grammarterm{delete-expression},
the pointer is used as the operand of a \grammarterm{delete-expression}\ubdef{lifetime.outside.pointer.delete},
\item
the pointer is used to access a non-static data member or call a
non-static member function of the object, or
non-static member function of the object\ubdef{lifetime.outside.pointer.member}, or
\item
the pointer is converted\iref{conv.ptr,expr.static.cast} to a pointer
to a virtual base class or to a base class thereof, or
to a virtual base class\ubdef{lifetime.outside.pointer.virtual} or
to a base class thereof, or
\item
the pointer is used as the operand of a
\keyword{dynamic_cast}\iref{expr.dynamic.cast}.
\keyword{dynamic_cast}\iref{expr.dynamic.cast}\ubdef{lifetime.outside.pointer.dynamic.cast}.
\end{itemize}
\begin{example}
\begin{codeblock}
Expand Down Expand Up @@ -4084,14 +4088,14 @@
a glvalue refers to
allocated storage\iref{basic.stc.dynamic.allocation}, and using the
properties of the glvalue that do not depend on its value is
well-defined. The program has undefined behavior if
well-defined. The program has undefined behavior if:
\begin{itemize}
\item the glvalue is used to access the object, or
\item the glvalue is used to call a non-static member function of the object, or
\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}, or
\item the glvalue is used to access the object\ubdef{lifetime.outside.glvalue.access}, or
\item the glvalue is used to call a non-static member function of the object\ubdef{lifetime.outside.glvalue.member}, or
\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}\ubdef{lifetime.outside.glvalue.virtual}, or
\item the glvalue is used as the operand of a
\keyword{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of
\keyword{typeid}.
\keyword{typeid}\ubdef{lifetime.outside.glvalue.dynamic.cast}.
\end{itemize}

\begin{note}
Expand Down Expand Up @@ -4176,7 +4180,7 @@
\end{footnote}
and another object of the original type does not occupy
that same storage location when the implicit destructor call takes
place, the behavior of the program is undefined. This is true
place, the behavior of the program is undefined\ubdef{original.type.implicit.destructor}. This is true
even if the block is exited with an exception.
\begin{example}
\begin{codeblock}
Expand All @@ -4196,7 +4200,7 @@
Creating a new object within the storage that a const, complete
object with static, thread, or automatic storage duration occupies,
or within the storage that such a const object used to occupy before
its lifetime ended, results in undefined behavior.
its lifetime ended, results in undefined behavior\ubdef{creating.within.const.complete.obj}.
\begin{example}
\begin{codeblock}
struct B {
Expand Down Expand Up @@ -4257,7 +4261,7 @@
then the value produced by that operator is erroneous.
Except in the following cases,
if an indeterminate value is produced by an evaluation,
the behavior is undefined, and
the behavior is undefined\ubdef{basic.indet.value}, and
if an erroneous value is produced by an evaluation,
the behavior is erroneous and
the result of the evaluation is that erroneous value:
Expand Down Expand Up @@ -4544,7 +4548,7 @@
does not satisfy the semantic constraints
specified in~\ref{basic.stc.dynamic.allocation}
and~\ref{basic.stc.dynamic.deallocation},
the behavior is undefined.
the behavior is undefined\ubdef{basic.stc.alloc.dealloc.constraint}.

\indextext{storage duration!dynamic|)}

Expand Down Expand Up @@ -4584,7 +4588,7 @@
\tcode{p0} represents the address of a block of storage disjoint from the storage
for any other object accessible to the caller.
The effect of indirecting through a pointer
returned from a request for zero size is undefined.
returned from a request for zero size is undefined\ubdef{basic.stc.alloc.zero.dereference}.
\begin{footnote}
The intent is
to have \tcode{\keyword{operator} \keyword{new}()} implementable by
Expand Down Expand Up @@ -4707,7 +4711,7 @@
signature.

\pnum
If a deallocation function terminates by throwing an exception, the behavior is undefined.
If a deallocation function terminates by throwing an exception, the behavior is undefined\ubdef{basic.stc.alloc.dealloc.throw}.
The value of the first argument supplied to a deallocation function may
be a null pointer value; if so, and if the deallocation function is one
supplied in the standard library, the call has no effect.
Expand Down Expand Up @@ -6087,7 +6091,7 @@
$P$ is not valid in the context of $E$,
then the behavior is undefined if $E$ is
an indirection\iref{expr.unary.op} or
an invocation of a deallocation function\iref{basic.stc.dynamic.deallocation},
an invocation of a deallocation function\iref{basic.stc.dynamic.deallocation}\ubdef{basic.compound.invalid.pointer},
and \impldef{invalid pointer value in the context of an evaluation} otherwise.
\begin{footnote}
Some implementations might define that
Expand Down Expand Up @@ -6607,7 +6611,7 @@
The value computations of the operands of an
operator are sequenced before the value computation of the result of the
operator.
The behavior is undefined if
The behavior is undefined\iref{intro.multithread}\ubdef{intro.execution.unsequenced.modification} if
\begin{itemize}
\item
\indextext{side effects}%
Expand Down Expand Up @@ -7015,7 +7019,7 @@
and neither happens before the other,
except for the special case for signal handlers described below.
Any such data race results in undefined
behavior.
behavior\ubdef{intro.races.data}.
\begin{note}
It can be shown that programs that correctly use mutexes
and \tcode{memory_order::seq_cst} operations to prevent all data races and use no
Expand Down Expand Up @@ -7074,8 +7078,8 @@
\rSec3[intro.progress]{Forward progress}

\pnum
The implementation may assume that any thread will eventually do one of the
following:
The implementation may assume\ubdef{intro.progress.stops} that any thread
will eventually do one of the following:
\begin{itemize}
\item terminate,
\item invoke the function \tcode{std::this_thread::yield}\iref{thread.thread.this},
Expand Down Expand Up @@ -7379,7 +7383,7 @@
objects with automatic storage duration\iref{class.dtor}. If
\tcode{std::exit} is invoked during the destruction of
an object with static or thread storage duration, the program has undefined
behavior.
behavior\ubdef{basic.start.main.exit.during.destruction}.

\pnum
\indextext{termination!program}%
Expand Down Expand Up @@ -7716,7 +7720,7 @@
\pnum
If a function contains a block variable of static or thread storage duration that has been
destroyed and the function is called during the destruction of an object with static or
thread storage duration, the program has undefined behavior if the flow of control
thread storage duration, the program has undefined behavior\ubdef{basic.start.term.use.after.destruction} if the flow of control
passes through the definition of the previously destroyed block variable.
\begin{note}
Likewise, the behavior is undefined
Expand Down Expand Up @@ -7744,7 +7748,7 @@
handlers\iref{support.runtime} that does not happen before\iref{intro.multithread}
completion of destruction of objects with static storage duration and execution of
\tcode{std::atexit} registered functions\iref{support.start.term}, the program has
undefined behavior.
undefined behavior
\begin{note}
If there is a use of an object with static storage
duration that does not happen before the object's destruction, the program has undefined
Expand Down Expand Up @@ -7793,7 +7797,7 @@
An invocation of the macro \tcode{va_start}\iref{cstdarg.syn}
shall not be a subexpression
of the predicate of a contract assertion,
no diagnostic required.
no diagnostic required\ifndrdef{basic.contract.vastart.contract.predicate}.

\pnum
\begin{note}
Expand Down Expand Up @@ -8199,6 +8203,6 @@
If the contract-violation handler
is not replaceable,
a declaration of a replacement function for the contract-violation handler
is ill-formed, no diagnostic required.
is ill-formed, no diagnostic required.\ifndrdef{basic.contract.handler.replacing.nonreplaceable}

\indextext{contract assertion|)}
25 changes: 13 additions & 12 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2335,7 +2335,7 @@

\pnum
Once a destructor is invoked for an object, the object's lifetime ends;
the behavior is undefined if the destructor is invoked
the behavior is undefined\ubdef{class.dtor.no.longer.exists} if the destructor is invoked
for an object whose lifetime has ended\iref{basic.life}.
\begin{example}
If the destructor for an object with automatic storage duration is explicitly invoked,
Expand Down Expand Up @@ -4006,7 +4006,7 @@
\indextext{definition!virtual function}%
A virtual function declared in a class shall be defined, or declared
pure\iref{class.abstract} in that class, or both; no diagnostic is
required\iref{basic.def.odr}.
required\iref{basic.def.odr}\ifndrdef{class.virtual.pure.or.defined}.
\indextext{friend!\tcode{virtual} and}%

\pnum
Expand Down Expand Up @@ -4240,7 +4240,7 @@
\indextext{virtual function call!undefined pure}%
the effect of making a virtual call\iref{class.virtual} to a pure
virtual function directly or indirectly for the object being created (or
destroyed) from such a constructor (or destructor) is undefined.%
destroyed) from such a constructor (or destructor) is undefined\ubdef{class.abstract.pure.virtual}.%
\indextext{derived class|)}

\rSec1[class.access]{Member access control}%
Expand Down Expand Up @@ -5525,7 +5525,7 @@
The target constructor is selected by overload resolution.
Once the target constructor returns, the body of the delegating constructor
is executed. If a constructor delegates to itself directly or indirectly,
the program is ill-formed, no diagnostic required.
the program is ill-formed, no diagnostic required\ifndrdef{class.base.init.delegate.itself}.
\begin{example}
\begin{codeblock}
struct C {
Expand Down Expand Up @@ -5840,7 +5840,7 @@
\item
a postcondition assertion of a destructor\iref{dcl.contract.func},
\end{itemize}
the program has undefined behavior.
the program has undefined behavior\ubdef{class.base.init.mem.fun}.
\begin{example}
\begin{codeblock}
class A {
Expand Down Expand Up @@ -6037,9 +6037,10 @@
\indextext{destruction!member access}%
For an object with a non-trivial constructor, referring to any non-static member
or base class of the object before the constructor begins execution results in
undefined behavior. For an object with a non-trivial destructor, referring to
undefined behavior\ubdef{class.cdtor.before.ctor}.
For an object with a non-trivial destructor, referring to
any non-static member or base class of the object after the destructor finishes
execution results in undefined behavior.
execution results in undefined behavior\ubdef{class.cdtor.after.dtor}.
\begin{example}
\begin{codeblock}
struct X { int i; };
Expand Down Expand Up @@ -6124,15 +6125,15 @@
indirectly derive from
\tcode{B}
shall have started and the destruction of these classes shall not have
completed, otherwise the conversion results in undefined behavior.
completed, otherwise the conversion results in undefined behavior\ubdef{class.cdtor.convert.pointer}.
To form a pointer to (or access the value of) a direct non-static member of
an object
\tcode{obj},
the construction of
\tcode{obj}
shall have started and its destruction shall not have completed,
otherwise the computation of the pointer value (or accessing the member
value) results in undefined behavior.
value) results in undefined behavior\ubdef{class.cdtor.form.pointer}.
\begin{example}
\begin{codeblock}
struct A { };
Expand Down Expand Up @@ -6176,7 +6177,7 @@
and the object expression refers to
the complete object of \tcode{x} or one of that object's base class subobjects
but not \tcode{x} or one of its base class subobjects, the behavior
is undefined.
is undefined\ubdef{class.cdtor.virtual.not.x}.
\begin{example}
\begin{codeblock}
struct V {
Expand Down Expand Up @@ -6233,7 +6234,7 @@
\tcode{typeid}
refers to the object under construction or destruction and the static type of
the operand is neither the constructor or destructor's class nor one of its
bases, the behavior is undefined.
bases, the behavior is undefined\ubdef{class.cdtor.typeid}.

\pnum
\indextext{construction!dynamic cast and}%
Expand All @@ -6258,7 +6259,7 @@
the operand is not a pointer to or object of the constructor or destructor's
own class or one of its bases, the
\keyword{dynamic_cast}
results in undefined behavior.
results in undefined behavior\ubdef{class.cdtor.dynamic.cast}.
\begin{example}
\begin{codeblock}
struct V {
Expand Down
Loading
Loading