Skip to content

Commit

Permalink
P2686R5 constexpr structured bindings and references to constexpr var…
Browse files Browse the repository at this point in the history
…iables

Editorial notes:
 * Merge the change to [temp.arg.nontype] with existing text.
  • Loading branch information
jensmaurer authored and tkoeppe committed Dec 16, 2024
1 parent 36271ad commit e220906
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 82 deletions.
63 changes: 49 additions & 14 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -441,24 +441,59 @@
A variable is named by an expression
if the expression is an \grammarterm{id-expression} that denotes it.
A variable \tcode{x} that is named by a
potentially-evaluated expression $E$
is \defnx{odr-used}{odr-use} by $E$ unless
potentially-evaluated expression $N$
that appears at a point $P$
is \defnx{odr-used}{odr-use} by $N$ unless
\begin{itemize}
\item
\tcode{x} is a reference that is
usable in constant expressions\iref{expr.const}, or
\tcode{x} is a reference
that is usable in constant expressions at $P$\iref{expr.const} or
\item
\tcode{x} is a variable of non-reference type that is
usable in constant expressions and has no mutable subobjects, and
$E$ is an element of the set of potential results of an expression
of non-volatile-qualified non-class type
to which the lvalue-to-rvalue conversion\iref{conv.lval} is applied, or
$N$ is an element of the set of potential results of an expression $E$, where
\begin{itemize}
\item
$E$ is a discarded-value expression\iref{expr.context}
to which the lvalue-to-rvalue conversion is not applied or
\item
\tcode{x} is a non-volatile object
that is usable in constant expressions at $P$ and
has no mutable subobjects and
\begin{itemize}
\item
$E$ is a class member access expression\iref{expr.ref}
naming a non-static data member of reference type and
whose object expression has non-volatile-qualified type or
\item
\tcode{x} is a variable of non-reference type, and
$E$ is an element of the set of potential results
of a discarded-value expression\iref{expr.context}
to which the lvalue-to-rvalue conversion is not applied.
the lvalue-to-rvalue conversion\iref{conv.lval} is applied to $E$ and
$E$ has non-volatile-qualified non-class type
\end{itemize}
\end{itemize}
\end{itemize}
\begin{example}
\begin{codeblock}
int f(int);
int g(int&);
struct A {
int x;
};
struct B {
int& r;
};
int h(bool cond) {
constexpr A a = {1};
constexpr const volatile A& r = a; // odr-uses \tcode{a}
int _ = f(cond ? a.x : r.x); // does not odr-use \tcode{a} or \tcode{r}
int x, y;
constexpr B b1 = {x}, b2 = {y}; // odr-uses \tcode{x} and \tcode{y}
int _ = g(cond ? b1.r : b2.r); // does not odr-use \tcode{b1} or \tcode{b2}
int _ = ((cond ? x : y), 0); // does not odr-use \tcode{x} or \tcode{y}
return [] {
return b1.r; // error: \tcode{b1} is odr-used here because the object
// referred to by \tcode{b1.r} is not constexpr-referenceable here
}();
}
\end{codeblock}
\end{example}

\pnum
A structured binding is odr-used if it appears as a potentially-evaluated expression.
Expand Down Expand Up @@ -6926,7 +6961,7 @@
\pnum
\indextext{initialization!constant}%
\defnx{Constant initialization}{constant initialization} is performed
if a variable or temporary object with static or thread storage duration
if a variable with static or thread storage duration
is constant-initialized\iref{expr.const}.
\indextext{initialization!zero-initialization}%
If constant initialization is not performed, a variable with static
Expand Down
32 changes: 25 additions & 7 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@
a \defn{structured binding declaration}\iref{dcl.struct.bind}.
Each \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq}
shall be
\tcode{constexpr},
\tcode{constinit},
\tcode{static},
\tcode{thread_local},
\tcode{auto}\iref{dcl.spec.auto}, or
Expand Down Expand Up @@ -849,7 +851,8 @@

\pnum
The \keyword{constexpr} specifier shall be applied only to
the definition of a variable or variable template or
the definition of a variable or variable template,
a structured binding declaration, or
the declaration of a function or function template.
The \keyword{consteval} specifier shall be applied only to
the declaration of a function or function template.
Expand Down Expand Up @@ -994,9 +997,7 @@
Such an object
shall have literal type and
shall be initialized.
In any \keyword{constexpr} variable declaration,
the full-expression of the initialization
shall be a constant expression\iref{expr.const}.
A \keyword{constexpr} variable shall be constant-initializable\iref{expr.const}.
A \keyword{constexpr} variable that is an object,
as well as any temporary to which a \keyword{constexpr} reference is bound,
shall have constant destruction.
Expand All @@ -1007,6 +1008,16 @@
};
constexpr pixel ur = { 1294, 1024 }; // OK
constexpr pixel origin; // error: initializer missing

namespace N {
void f() {
int x;
constexpr int& ar = x; // OK
static constexpr int& sr = x; // error: \tcode{x} is not constexpr-representable
// at the point indicated below
}
// immediate scope here is that of \tcode{N}
}
\end{codeblock}
\end{example}

Expand All @@ -1015,7 +1026,12 @@

\pnum
The \keyword{constinit} specifier shall be applied only
to a declaration of a variable with static or thread storage duration.
to a declaration of a variable with static or thread storage duration
or to a structured binding declaration\iref{dcl.struct.bind}.
\begin{note}
A structured binding declaration introduces a uniquely named variable,
to which the \tcode{constinit} specifier applies.
\end{note}
If the specifier is applied to any declaration of a variable,
it shall be applied to the initializing declaration.
No diagnostic is required if no \keyword{constinit} declaration
Expand Down Expand Up @@ -7033,8 +7049,10 @@
appertains to the structured binding so introduced.
Let \cv{} denote the \grammarterm{cv-qualifier}{s} in
the \grammarterm{decl-specifier-seq} and
\placeholder{S} consist of the \grammarterm{storage-class-specifier}{s} of
the \grammarterm{decl-specifier-seq} (if any).
\placeholder{S} consist of
each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq}
that is \tcode{constexpr}, \tcode{constinit}, or
a \grammarterm{storage-class-specifier}.
A \cv{} that includes \tcode{volatile} is deprecated;
see~\ref{depr.volatile.type}.
First, a variable with a unique name \exposid{e} is introduced. If the
Expand Down
Loading

0 comments on commit e220906

Please sign in to comment.