Skip to content

Commit 188ec4a

Browse files
tkoeppezygoloid
authored andcommitted
P0292R2 constexpr if: a slightly different syntax
1 parent 131bc32 commit 188ec4a

File tree

5 files changed

+69
-14
lines changed

5 files changed

+69
-14
lines changed

source/basic.tex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,13 @@
370370

371371
\pnum
372372
Every program shall contain exactly one definition of every non-inline
373-
function or variable that is odr-used in that program; no diagnostic required.
373+
function or variable that is odr-used in that program
374+
outside of a discarded statement~(\ref{stmt.if}); no diagnostic required.
374375
The definition can appear explicitly in the program, it can be found in
375376
the standard or a user-defined library, or (when appropriate) it is
376377
implicitly defined (see~\ref{class.ctor}, \ref{class.dtor} and
377378
\ref{class.copy}). An inline function shall be defined in every
378-
translation unit in which it is odr-used.
379+
translation unit in which it is odr-used outside of a discarded statement.
379380

380381
\pnum
381382
\indextext{type!incomplete}%

source/declarations.tex

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,8 @@
15501550
the declared return type of the function. Otherwise, the function declarator
15511551
shall declare a function. If the declared return type of the
15521552
function contains a placeholder type, the return type of the function is
1553-
deduced from \tcode{return} statements in the body of the function, if any.
1553+
deduced from non-discarded \tcode{return} statements, if any, in the body
1554+
of the function~(\ref{stmt.if}).
15541555

15551556
\pnum
15561557
If the \tcode{auto} \grammarterm{type-specifier} appears as one of the
@@ -1633,13 +1634,13 @@
16331634

16341635
\pnum
16351636
If a function with a declared return type that contains a placeholder type has
1636-
multiple \tcode{return} statements, the return type is deduced for each
1637+
multiple non-discarded \tcode{return} statements, the return type is deduced for each
16371638
\tcode{return} statement. If the type deduced is not the same in each
16381639
deduction, the program is ill-formed.
16391640

16401641
\pnum
16411642
If a function with a declared return type that uses a placeholder type has no
1642-
\tcode{return} statements, the return type is deduced as though from a
1643+
non-discarded \tcode{return} statements, the return type is deduced as though from a
16431644
\tcode{return} statement with no operand at the closing brace of the function
16441645
body.
16451646
\begin{example}
@@ -1652,7 +1653,7 @@
16521653
\pnum
16531654
If the type of an entity with an undeduced placeholder type is needed to
16541655
determine the type of an expression, the program is ill-formed. Once a
1655-
\tcode{return} statement has been seen in a function, however, the return type deduced
1656+
non-discarded \tcode{return} statement has been seen in a function, however, the return type deduced
16561657
from that statement can be used in the rest of the function, including in other
16571658
\tcode{return} statements.
16581659
\begin{example}
@@ -1786,9 +1787,10 @@
17861787
A type \tcode{T} containing a placeholder type,
17871788
and a corresponding initializer \tcode{e},
17881789
are determined as follows:
1790+
17891791
\begin{itemize}
17901792
\item
1791-
for a \tcode{return} statement that occurs
1793+
for a non-discarded \tcode{return} statement that occurs
17921794
in a function declared with a return type
17931795
that contains a placeholder type,
17941796
\tcode{T} is the declared return type
@@ -1811,6 +1813,7 @@
18111813
\tcode{T} is the declared type of the non-type template parameter
18121814
and \tcode{e} is the corresponding template argument.
18131815
\end{itemize}
1816+
18141817
In the case of a \tcode{return} statement with no operand
18151818
or with an operand of type \tcode{void},
18161819
\tcode{T} shall be either
@@ -1885,6 +1888,7 @@
18851888
decltype(auto)*x7d = &i; // error, declared type is not plain \tcode{decltype(auto)}
18861889
\end{codeblock}
18871890
\end{example}
1891+
18881892
\rSec1[dcl.enum]{Enumeration declarations}%
18891893
\indextext{enumeration}%
18901894
\indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}%

source/grammar.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,8 +867,8 @@
867867

868868
\begin{bnf}
869869
\nontermdef{selection-statement}\br
870-
\terminal{if (} condition \terminal{)} statement\br
871-
\terminal{if (} condition \terminal{)} statement \terminal{else} statement\br
870+
\terminal{if constexpr\opt (} condition \terminal{)} statement\br
871+
\terminal{if constexpr\opt (} condition \terminal{)} statement \terminal{else} statement\br
872872
\terminal{switch (} condition \terminal{)} statement
873873
\end{bnf}
874874

source/statements.tex

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@
128128
%
129129
\begin{bnf}
130130
\nontermdef{selection-statement}\br
131-
\terminal{if (} condition \terminal{)} statement\br
132-
\terminal{if (} condition \terminal{)} statement \terminal{else} statement\br
131+
\terminal{if constexpr\opt (} condition \terminal{)} statement\br
132+
\terminal{if constexpr\opt (} condition \terminal{)} statement \terminal{else} statement\br
133133
\terminal{switch (} condition \terminal{)} statement
134134
\end{bnf}
135135

@@ -245,6 +245,50 @@
245245
an \tcode{else} part.\footnote{In other words, the \tcode{else} is associated with the nearest un-elsed
246246
\tcode{if}.}
247247

248+
\pnum
249+
If the parenthesized \grammarterm{condition} is prefixed with
250+
\tcode{constexpr}, the value of the condition shall be a contextually
251+
converted constant expression of type \tcode{bool}~(\ref{expr.const}); this
252+
form is called a \defn{constexpr if} statement. If the value of the
253+
converted condition is \tcode{false}, the first substatement is a
254+
\defn{discarded statement}, otherwise the second substatement, if
255+
present, is a discarded statement. During the instantation of an
256+
enclosing templated entity, if the condition is not value-dependent
257+
after its instantiation, the discarded substatement (if any) is not
258+
instantiated.
259+
\begin{note}
260+
Odr-uses~(\ref{basic.def.odr}) in a discarded statement do not require
261+
an entity to be defined.
262+
\end{note}
263+
A \tcode{case} or \tcode{default} label appearing within such an
264+
\tcode{if} statement shall be associated with a \tcode{switch}
265+
statement~(\ref{stmt.switch}) within the same \tcode{if} statement.
266+
A label~(\ref{stmt.label}) declared in a substatement of a \tcode{constexpr if}
267+
statement shall only be referred to by a statement~(\ref{stmt.goto}) in
268+
the same substatement.
269+
\begin{example}
270+
\begin{codeblock}
271+
template<typename T, typename ... Rest> void g(T&& p, Rest&& ...rs) {
272+
// ... handle \tcode{p}
273+
274+
if constexpr (sizeof...(rs) > 0)
275+
g(rs...); // never instantiated with an empty argument list.
276+
}
277+
278+
extern int x; // no definition of \tcode{x} required
279+
280+
int f() {
281+
if constexpr (true)
282+
return 0;
283+
else if (x)
284+
return x;
285+
else
286+
return -x;
287+
}
288+
}
289+
\end{codeblock}
290+
\end{example}
291+
248292
\rSec2[stmt.switch]{The \tcode{switch} statement}%
249293
\indextext{statement!\idxcode{switch}}
250294

source/templates.tex

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,8 @@
12991299
definition which is unrelated to
13001300
the function template definition or to any other default arguments or
13011301
\grammarterm{exception-specification}{s}.
1302+
For the purpose of instantiation, the substatements of a \tcode{constexpr if}
1303+
statement~(\ref{stmt.if}) are considered definitions.
13021304

13031305
\pnum
13041306
Because an \grammarterm{alias-declaration} cannot declare a
@@ -3143,10 +3145,12 @@
31433145
Knowing which names are type names allows the syntax of every template
31443146
to be checked.
31453147
The program is ill-formed, no diagnostic required, if:
3148+
31463149
\begin{itemize}
31473150
\item
31483151
no valid specialization can be generated for a template
3149-
and that template is not instantiated, or
3152+
or a substatement of a \tcode{constexpr if} statement~(\ref{stmt.if}) within a template
3153+
and the template is not instantiated, or
31503154
\item
31513155
every valid specialization of a variadic template requires an empty template
31523156
parameter pack, or
@@ -3189,6 +3193,7 @@
31893193
\end{itemize}
31903194
\end{note}
31913195
\end{itemize}
3196+
31923197
Otherwise, no diagnostic shall be issued for a template
31933198
for which a valid specialization can be generated.
31943199
\begin{note}
@@ -4697,8 +4702,9 @@
46974702
\pnum
46984703
An implementation shall not implicitly instantiate a function template,
46994704
a variable template,
4700-
a member template, a non-virtual member function, a member class, or a
4701-
static data member of a class template that does not require instantiation.
4705+
a member template, a non-virtual member function, a member class, a
4706+
static data member of a class template, or a substatement of a \tcode{constexpr if}
4707+
statement (\ref{stmt.if}), unless such instantiation is required.
47024708
It is unspecified whether or not an implementation implicitly instantiates a
47034709
virtual member function of a class template if the virtual member function would
47044710
not otherwise be instantiated.

0 commit comments

Comments
 (0)