[stmt.select]

# 8 Statements [[stmt]](./#stmt)

## 8.5 Selection statements [stmt.select]

### [8.5.1](#general) General [[stmt.select.general]](stmt.select.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L276)

Selection statements choose one of several flows of control[.](#general-1.sentence-1)

[selection-statement:](#nt:selection-statement "8.5.1 General [stmt.select.general]")  
if constexpropt ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
if constexpropt ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*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]")  
if !opt consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")  
if !opt consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") else [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
switch ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")

See [[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators") for the optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in a condition[.](#general-1.sentence-2)

[*Note [1](#general-note-1)*:

An [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]") ends with a semicolon[.](#general-1.sentence-3)

â *end note*]

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L296)

[*Note [2](#general-note-2)*:

Each [*selection-statement*](#nt:selection-statement "8.5.1 General [stmt.select.general]") and
each substatement of a [*selection-statement*](#nt:selection-statement "8.5.1 General [stmt.select.general]") has a block scope ([[basic.scope.block]](basic.scope.block "6.4.3 Block scope"))[.](#general-2.sentence-1)

â *end note*]

### [8.5.2](#stmt.if) The if statement [[stmt.if]](stmt.if)

[1](#stmt.if-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[.](#stmt.if-1.sentence-1)

If the else part of the selection
statement is present and the condition yields false, the second
substatement is executed[.](#stmt.if-1.sentence-2)

If the first substatement is reached via a
label, the condition is not evaluated and the second substatement is
not executed[.](#stmt.if-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[.](#stmt.if-1.sentence-4)[72](#footnote-72 "In other words, the else is associated with the nearest un-elsed if.")

[2](#stmt.if-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[.](#stmt.if-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[.](#stmt.if-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[.](#stmt.if-2.sentence-3)

Each substatement of a constexpr if statement is a control-flow-limited
statement ([[stmt.label]](stmt.label "8.2 Label"))[.](#stmt.if-2.sentence-4)

[*Example [1](#stmt.if-example-1)*: if constexpr (sizeof(int[2])) {} // OK, narrowing allowed â *end example*]

[*Note [1](#stmt.if-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[.](#stmt.if-2.sentence-5)

â *end note*]

[*Example [2](#stmt.if-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](#stmt.if-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]")[.](#stmt.if-3.sentence-1)

[4](#stmt.if-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]")[.](#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]")[.](#stmt.if-4.sentence-2)

[*Example [3](#stmt.if-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](#stmt.if-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[.](#stmt.if-5.sentence-1)

[*Note [2](#stmt.if-note-2)*:

The first substatement is an immediate function context[.](#stmt.if-5.sentence-2)

â *end note*]

Otherwise, if the else part of the selection statement is present,
then the second substatement is executed[.](#stmt.if-5.sentence-3)

Each substatement of a consteval if statement is a control-flow-limited
statement ([[stmt.label]](stmt.label "8.2 Label"))[.](#stmt.if-5.sentence-4)

[6](#stmt.if-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)

### [8.5.3](#stmt.switch) The switch statement [[stmt.switch]](stmt.switch)

[1](#stmt.switch-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L444)

The switch statement causes control to be transferred to one of
several statements depending on the value of a condition[.](#stmt.switch-1.sentence-1)

[2](#stmt.switch-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L448)

If the [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") is an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]"),
the value of the condition is the value of the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]");
otherwise, it is the value of the decision variable[.](#stmt.switch-2.sentence-1)

The value of the condition shall be of integral type, enumeration type, or class
type[.](#stmt.switch-2.sentence-2)

If of class type, the
condition is [contextually implicitly converted](conv#def:contextually_implicitly_converted "7.3 Standard conversions [conv]") to
an integral or enumeration type[.](#stmt.switch-2.sentence-3)

If the (possibly converted) type is subject to [integral
promotions](conv.prom "7.3.7 Integral promotions [conv.prom]"), the condition is converted
to the promoted type[.](#stmt.switch-2.sentence-4)

Any
statement within the switch statement can be labeled with one or
more case labels as follows:

case [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") :

where the [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") shall be
a converted [constant expression](expr.const "7.7 Constant expressions [expr.const]") of the
adjusted type of the switch condition[.](#stmt.switch-2.sentence-5)

No two of the case constants in
the same switch shall have the same value after conversion[.](#stmt.switch-2.sentence-6)

[3](#stmt.switch-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L471)

There shall be at most one label of the formdefault : within a switch statement[.](#stmt.switch-3.sentence-1)

[4](#stmt.switch-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L479)

Switch statements can be nested; a case or default label
is associated with the smallest switch enclosing it[.](#stmt.switch-4.sentence-1)

[5](#stmt.switch-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L483)

When the switch statement is executed, its condition is
evaluated[.](#stmt.switch-5.sentence-1)

If one of the case constants has the same value as the condition,
control is passed to the statement following the matched case label[.](#stmt.switch-5.sentence-2)

If
no case constant matches the condition, and if there is adefault label, control passes to the statement labeled by the
default label[.](#stmt.switch-5.sentence-3)

If no case matches and if there is no default then none of the statements in the switch is executed[.](#stmt.switch-5.sentence-4)

[6](#stmt.switch-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L495)

case and default labels in themselves do not alter the
flow of control, which continues unimpeded across such labels[.](#stmt.switch-6.sentence-1)

To exit
from a switch, see break, [[stmt.break]](stmt.break "8.8.2 The break statement")[.](#stmt.switch-6.sentence-2)

[*Note [1](#stmt.switch-note-1)*:

Usually, the substatement that is the subject of a switch is compound
and case and default labels appear on the top-level
statements contained within the (compound) substatement, but this is not
required[.](#stmt.switch-6.sentence-3)

Declarations can appear in the substatement of aswitch statement[.](#stmt.switch-6.sentence-4)

â *end note*]

[7](#stmt.switch-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L509)

A switch statement of the form

switch ( [*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]")  
 switch ( [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ) [*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]")[.](#stmt.switch-7.sentence-1)
