Transfers control to one of several statements, depending on the value of a condition.
- 1 Syntax
- 2 Condition
- 2.1 Expression
- 2.2 Declaration
- 2.2.1 Non-structured binding declaration
- 2.2.2 Structured binding declaration
- 2.3 Type
- 3 Labels
- 4 Control flow transfer
- 5 switch statements with initializer
- 6 Notes
- 7 Keywords
- 8 Example
- 9 Defect reports
- 10 See also
- 11 External links
[edit] Syntax
attr (optional) switch ( init-statement (optional) condition ) statement attr – (since C++11) any number of attributes init-statement – (since C++17) any of the following:
- an expression statement (which may be a null statement 😉
- a simple declaration, typically a declaration of a variable with initializer, but it may declare arbitrarily many variables or structured bindings
- an alias declaration
(since C++23)
Note that any init-statement must end with a semicolon. This is why it is often described informally as an expression or a declaration followed by a semicolon.
condition – a condition statement – a statement (typically a compound statement)
[edit] Condition
A condition can either be an expression or a simple declaration.
- If it can be syntactically resolved as a structured binding declaration, it is interpreted as a structured binding declaration.
(since C++26)
- If it can be syntactically resolved as an expression, it is treated as an expression. Otherwise, it is treated as a declaration that is not a structured binding declaration(since C++26).
When control reaches condition, the condition will yield a value, which is used to determine which label the control will go to.
[edit] Expression
If condition is an expression, the value it yields is the the value of the expression.
[edit] Declaration
If condition is a simple declaration, the value it yields is the value of the decision variable (see below).
[edit] Non-structured binding declaration
The declaration has the following restrictions:
- Syntactically conforms to the following form:
- type-specifier-seq declarator = assignment-expression
(until C++11)
- attribute-specifier-seq(optional) decl-specifier-seq declarator brace-or-equal-initializer
(since C++11)
- The declarator cannot specify a function or an array.
- The type specifier sequence(until C++11)declaration specifier sequence can only contain type specifiers and constexpr, and it(since C++11) cannot define a class or enumeration.
The decision variable of the declaration is the declared variable.
Structured binding declaration
The declaration has the following restrictions:
- The expression in its initializer cannot be of an array type.
- The declaration specifier sequence can only contain type specifiers and constexpr.
The decision variable of the declaration is the invented variable e introduced by the declaration.
(since C++26)
[edit] Type
condition can only yield the following types:
- integral types
- enumeration types
- class types
If the yielded value is of a class type, it is contextually implicitly converted to an integral or enumeration type.
If the (possibly converted) type is subject to integral promotions , the yielded value is converted to the promoted type.
[edit] Labels
Any statement within the switch statement can be labeled with one or more following labels:
attr (optional) case constant-expression : (1) attr (optional) default: (2) attr – (since C++11) any number of attributes constant-expression – a converted constant expression of the adjusted type of the switch condition
A case or default label is associated with the innermost switch statement enclosing it.
If any of the following conditions is satisfied, the program is ill-formed:
- A switch statement is associated with multiple case labels whose constant-expression s have the same value after conversions.
- A switch statement is associated with multiple default labels.
[edit] Control flow transfer
When the condition of a switch statement yields a (possibly converted) value:
- If one of the associated case label constants has the same value, control is passed to the statement labeled by the matched case label.
- Otherwise, if there is an associated default label, control is passed to the statement labeled by the default label.
- Otherwise, none of the statements in the switch statement will be executed.
case and default labels in themselves do not alter the flow of control. To exit from a switch statement from the middle, see break statements.
Compilers may issue warnings on fallthrough (reaching the next case or default label without a break) unless the attribute [[fallthrough]] appears immediately before the case label to indicate that the fallthrough is intentional(since C++17).
switch statements with initializer
If init-statement is used, the switch statement is equivalent to
{ init-statement switch ( condition ) statement
}
Except that names declared by the init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope, which is also the scope of statement.
(since C++17)
[edit] Notes
Because transfer of control is not permitted to enter the scope of a variable, if a declaration statement is encountered inside the statement, it has to be scoped in its own compound statement:
[edit] Keywords
switch, case, default
[edit] Example
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior CWG 1767 C++98 condition s of types that are not subject tointegral promotion could not be promoted do not promotecondition s of these types CWG 2629 C++98 condition could be a declaration of a floating-point variable prohibited
[edit] See also
[edit] External links
1. Loop unrolling using Duff’s Device 2. Duff’s device can be used to implement coroutines in C/C++





