Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2686R5 constexpr structured bindings and references to constexpr variables #7468

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
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 @@ -6886,7 +6921,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 @@ -213,6 +213,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 @@ -850,7 +852,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 @@ -995,9 +998,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 @@ -1008,6 +1009,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 @@ -1016,7 +1027,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 @@ -7030,8 +7046,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
Loading