147 lines
6.7 KiB
Markdown
147 lines
6.7 KiB
Markdown
[stmt.if]
|
||
|
||
# 8 Statements [[stmt]](./#stmt)
|
||
|
||
## 8.5 Selection statements [[stmt.select]](stmt.select#stmt.if)
|
||
|
||
### 8.5.2 The if statement [stmt.if]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L307)
|
||
|
||
If the condition ([[stmt.pre]](stmt.pre "8.1 Preamble")) yields true, the first
|
||
substatement is executed[.](#1.sentence-1)
|
||
|
||
If the else part of the selection
|
||
statement is present and the condition yields false, the second
|
||
substatement is executed[.](#1.sentence-2)
|
||
|
||
If the first substatement is reached via a
|
||
label, the condition is not evaluated and the second substatement is
|
||
not executed[.](#1.sentence-3)
|
||
|
||
In the second form of if statement
|
||
(the one including else), if the first substatement is also anif statement then that inner if statement shall contain
|
||
an else part[.](#1.sentence-4)[72](#footnote-72 "In other words, the else is associated with the nearest un-elsed if.")
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L322)
|
||
|
||
If the if statement is of the form if constexpr,
|
||
the value of the condition
|
||
is contextually converted to bool and
|
||
the converted expression shall be a constant expression ([[expr.const]](expr.const "7.7 Constant expressions"));
|
||
this
|
||
form is called a [*constexpr if*](#def:constexpr_if "8.5.2 The if statement [stmt.if]") statement[.](#2.sentence-1)
|
||
|
||
If the value of the
|
||
converted condition is false, the first substatement is a[*discarded statement*](#def:discarded_statement "8.5.2 The if statement [stmt.if]"), otherwise the second substatement, if
|
||
present, is a discarded statement[.](#2.sentence-2)
|
||
|
||
During the instantiation of an
|
||
enclosing templated entity ([[temp.pre]](temp.pre "13.1 Preamble")), if the condition is
|
||
not value-dependent after its instantiation, the discarded substatement
|
||
(if any) is not instantiated[.](#2.sentence-3)
|
||
|
||
Each substatement of a constexpr if statement is a control-flow-limited
|
||
statement ([[stmt.label]](stmt.label "8.2 Label"))[.](#2.sentence-4)
|
||
|
||
[*Example [1](#example-1)*: if constexpr (sizeof(int[2])) {} // OK, narrowing allowed â *end example*]
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
Odr-uses ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) in a discarded statement do not require
|
||
an entity to be defined[.](#2.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#example-2)*: template<typename T, typename ... Rest> void g(T&& p, Rest&& ...rs) {// ... handle pif constexpr (sizeof...(rs) > 0) g(rs...); // never instantiated with an empty argument list}extern int x; // no definition of x requiredint f() {if constexpr (true)return 0; else if (x)return x; elsereturn -x;} â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L368)
|
||
|
||
An if statement of the form
|
||
|
||
if constexpropt ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")
|
||
|
||
is equivalent to
|
||
|
||
{
|
||
[*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")
|
||
if constexpropt ( [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")
|
||
}
|
||
|
||
and an if statement of the form
|
||
|
||
if constexpropt ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]") else [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")
|
||
|
||
is equivalent to
|
||
|
||
{
|
||
[*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")
|
||
if constexpropt ( [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]") else [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")
|
||
}
|
||
|
||
except that the [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") is
|
||
in the same scope as the [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]")[.](#3.sentence-1)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L394)
|
||
|
||
An if statement of the form if consteval is called a [*consteval if statement*](#def:statement,consteval_if "8.5.2 The if statement [stmt.if]")[.](#4.sentence-1)
|
||
|
||
The [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]"), if any, in a consteval if statement
|
||
shall be a [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")[.](#4.sentence-2)
|
||
|
||
[*Example [3](#example-3)*: constexpr void f(bool b) {if (true)if consteval { }else ; // error: not a [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]"); else not associated with outer if} â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L409)
|
||
|
||
If a consteval if statement is evaluated in a context
|
||
that is manifestly constant-evaluated ([[expr.const]](expr.const "7.7 Constant expressions")),
|
||
the first substatement is executed[.](#5.sentence-1)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
The first substatement is an immediate function context[.](#5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
Otherwise, if the else part of the selection statement is present,
|
||
then the second substatement is executed[.](#5.sentence-3)
|
||
|
||
Each substatement of a consteval if statement is a control-flow-limited
|
||
statement ([[stmt.label]](stmt.label "8.2 Label"))[.](#5.sentence-4)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L421)
|
||
|
||
An if statement of the form
|
||
|
||
if ! consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")
|
||
|
||
is not itself a consteval if statement,
|
||
but is equivalent to the consteval if statement
|
||
|
||
if consteval { } else [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")
|
||
|
||
An if statement of the form
|
||
|
||
if ! consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")1 else [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")2
|
||
|
||
is not itself a consteval if statement,
|
||
but is equivalent to the consteval if statement
|
||
|
||
if consteval [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")2 else [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")1
|
||
|
||
[72)](#footnote-72)[72)](#footnoteref-72)
|
||
|
||
In other words, the else is associated with the nearest un-elsedif[.](#footnote-72.sentence-1)
|