Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/switch"

From cppreference.com
< cpp‎ | language
m (Undo revision 113072 by Mnaydenov (talk) this was an very basic example showing what default: does, adding std::plus makes it seem like it's about something else)
(No need to explain the usage in “Keywords” section.)
 
(38 intermediate revisions by 12 users not shown)
Line 1: Line 1:
{{title|switch statement}}
+
{{title|{{tt|switch}} statement}}
 
{{cpp/language/statements/navbar}}
 
{{cpp/language/statements/navbar}}
Transfers control to one of the several statements, depending on the value of a condition.
+
Transfers control to one of several statements, depending on the value of a condition.
  
 
===Syntax===
 
===Syntax===
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc|notes={{mark until c++17}}|1=
+
{{sdsc|
{{spar|attr}}{{mark optional}} {{ttb|switch}} {{ttb|(}} {{spar|condition}} {{ttb|)}} {{spar|statement}}
+
{{spar optional|attr}} {{ttb|switch}} {{ttb|(}} {{spar optional|init-statement}} {{spar|condition}} {{ttb|)}} {{spar|statement}}  
}}
+
 
+
{{sdsc|notes={{mark since c++17}}|1=
+
{{spar|attr}}{{mark optional}} {{ttb|switch}} {{ttb|(}} {{spar|init-statement}}{{mark optional}} {{spar|condition}} {{ttb|)}} {{spar|statement}}  
+
 
}}
 
}}
 
{{sdsc end}}
 
{{sdsc end}}
  
 
{{par begin}}
 
{{par begin}}
{{par | {{spar|attr}}{{mark c++11}} | any number of {{rlp|attributes}} }}
+
{{par|{{spar|attr}}|{{mark since c++11}} any number of {{rlp|attributes}}}}
{{par | {{spar|condition}} | any {{rlp|expressions|expression}} of integral or enumeration type, or of a class type {{rlp|implicit cast|contextually implicitly convertible}} to an integral or enumeration type, or a {{rlp|declarations|declaration}} of a single non-array variable of such type with a brace-or-equals {{rlp|initialization|initializer}}.}}
+
{{par|{{spar|init-statement}}|{{mark since c++17}} any of the following:
{{par | {{spar|init-statement}}{{mark c++17}} | either
+
* an {{rlp|statements#Expression statements|expression statement}} (which may be a null statement {{c|;}})
* an {{rlp|statements#Expression_statements|expression statement}} (which may be a ''null statement'' "{{ttb|;}}")
+
* a {{rlpsd|declarations#Simple declaration}}, typically a declaration of a variable with initializer, but it may declare arbitrarily many variables or {{rlp|structured binding}}s
* a {{rlp|declarations|simple declaration}}, typically a declaration of a variable with initializer, but it may declare arbitrary many variables or structured bindings
+
{{rrev|since=c++23|
:Note that any {{spar|init-statement}} must end with a semicolon {{ttb|;}}, which is why it is often described informally as an expression or a declaration followed by a semicolon.}}
+
* an {{rlp|type alias|alias declaration}}
{{par | {{spar|statement}} | any {{rlp|statements|statement}} (typically a compound statement). {{ttb|case:}} and {{ttb|default:}} labels are permitted in {{spar|statement}} and {{c|break;}} statement has special meaning.}}
+
}}
 +
Note that any {{spar|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.}}
 +
{{par|{{spar|condition}}|a [[#Condition|condition]]}}
 +
{{par|{{spar|statement}}|a statement (typically a compound statement)}}
 
{{par end}}
 
{{par end}}
  
 +
{{cpp/language/condition|usage=determine which label the control will go to}}
 +
 +
====Type====
 +
{{spar|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 {{rlpsd|implicit conversion#Integral promotion}}s , the yielded value is converted to the promoted type.
 +
 +
===Labels===
 +
Any statement within the {{c/core|switch}} statement can be labeled with one or more following labels:
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc|num=1|1=
+
{{sdsc|num=1|
{{spar|attr}}{{mark optional}} {{ttb|case}} {{spar|constant_expression}} {{ttb|:}} {{spar|statement}}
+
{{spar optional|attr}} {{ttb|case}} {{spar|constant-expression}} {{ttb|:}}
 
}}
 
}}
{{sdsc|num=2|1=
+
{{sdsc|num=2|
{{spar|attr}}{{mark optional}} {{ttb|default}} {{ttb|:}} {{spar|statement}}
+
{{spar optional|attr}} {{ttb|default:}}
 
}}
 
}}
 
{{sdsc end}}
 
{{sdsc end}}
  
 
{{par begin}}
 
{{par begin}}
{{par | {{spar|constant_expression}} | a constant expression of the same type as the type of {{spar|condition}} after conversions and {{rlp|implicit_cast|integral promotions}} }}
+
{{par|{{spar|attr}}|{{mark since c++11}} any number of {{rlp|attributes}}}}
 +
{{par|{{spar|constant-expression}}|a {{rlpsd|constant expression#Converted constant expression}} of the adjusted type of the {{c/core|switch}} condition}}
 
{{par end}}
 
{{par end}}
  
===Explanation===
 
The body of a switch statement may have an arbitrary number of {{tt|case:}} labels, as long as the values of all {{spar|constant_expressions}} are unique (after conversions/promotions). At most one {{tt|default:}} label may be present (although nested switch statements may use their own {{tt|default:}} labels or have {{tt|case:}} labels whose constants are identical to the ones used in the enclosing switch)
 
  
If {{spar|condition}} evaluates to the value that is equal to the value of one of {{spar|constant_expression}}s, then control is transferred to the statement that is labeled with that {{spar|constant_expression}}.
+
A {{c/core|case}} or {{c/core|default}} label is associated with the innermost {{c/core|switch}} statement enclosing it.
  
If {{spar|condition}} evaluates to the value that doesn't match any of the {{tt|case:}} labels, and the {{tt|default:}} label is present, control is transferred to the statement labeled with the {{tt|default:}} label.
+
If any of the following conditions is satisfied, the program is ill-formed:
 +
* A {{c/core|switch}} statement is associated with multiple {{c/core|case}} labels whose {{spar sep|constant-expression}}s have the same value after conversions.
 +
* A {{c/core|switch}} statement is associated with multiple {{c/core|default}} labels.
  
The {{rlp|break}} statement, when encountered in {{spar|statement}} exits the switch statement:
+
===Control flow transfer===
 +
When the condition of a {{c/core|switch}} statement yields a (possibly converted) value:
 +
* If one of the associated {{c/core|case}} label constants has the same value, control is passed to the statement labeled by the matched {{c/core|case}} label.
 +
* Otherwise, if there is an associated {{c/core|default}} label, control is passed to the statement labeled by the {{c/core|default}} label.
 +
* Otherwise, none of the statements in the {{c/core|switch}} statement will be executed.
  
{{source|switch(1) {
+
{{c/core|case}} and {{c/core|default}} labels in themselves do not alter the flow of control. To exit from a {{c/core|switch}} statement from the middle, see {{rlp|break|{{c/core|break}} statements}}.
     case 1 : cout << '1'; // prints "1",
+
 
     case 2 : cout << '2'; // then prints "2"
+
Compilers may issue warnings on fallthrough (reaching the next {{c/core|case}} or {{c/core|default}} label without a {{c/core|break}}){{rev inl|since=c++17| unless the attribute {{attr|fallthrough}} appears immediately before the {{c/core|case}} label to indicate that the fallthrough is intentional}}.
 +
 
 +
{{source|
 +
switch (1)
 +
{
 +
     case 1:
 +
        std::cout << '1'; // prints "1",
 +
     case 2:
 +
        std::cout << '2'; // then prints "2"
 
}
 
}
 
}}
 
}}
{{source|switch(1) {
+
{{source|
     case 1 : cout << '1'; // prints "1"
+
switch (1)
            break;       // and exits the switch
+
{
     case 2 : cout << '2';
+
     case 1:
            break;
+
        std::cout << '1'; // prints "1"
 +
        break;           // and exits the switch
 +
     case 2:
 +
        std::cout << '2';
 +
        break;
 
}
 
}
 
}}
 
}}
  
{{rev begin}}
+
{{rrev|since=c++17|
{{rev|since=c++17|
+
{{anchor|switch statements with initializer}}
Compilers may issue warnings on fallthrough (reaching the next case label without a break) unless the attribute {{rlp|attributes|{{tt|<nowiki>[[</nowiki>fallthrough<nowiki>]]</nowiki>}}}} appears immediately before the case label to indicate that the fallthrough is intentional.
+
==={{c/core|switch}} statements with initializer===
 
+
 
If {{spar|init-statement}} is used, the switch statement is equivalent to
 
If {{spar|init-statement}} is used, the switch statement is equivalent to
  
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc |  
+
{{sdsc|
 
{{ttb|{}}<br>
 
{{ttb|{}}<br>
:{{spar|init_statement}} <br>
+
:{{spar|init-statement}}<br>
:{{ttb|switch}} {{ttb|(}} {{spar|condition}} {{ttb|)}} {{spar|statement}} <br>
+
:{{ttb|switch}} {{ttb|(}} {{spar|condition}} {{ttb|)}} {{spar|statement}}<br>
{{ttb|} }}
+
{{ttb|}}}
 
}}
 
}}
 
{{sdsc end}}
 
{{sdsc end}}
Except that names declared by the {{spar|init-statement}} (if {{spar|init-statement}} is a declaration) and names declared by {{spar|condition}} (if condition is a declaration) are in the same scope, which is also the scope of {{spar|statement}}.
 
}}{{rev end}}
 
  
 +
Except that names declared by the {{spar|init-statement}} (if {{spar|init-statement}} is a declaration) and names declared by {{spar|condition}} (if {{spar|condition}} is a declaration) are in the same scope, which is also the scope of {{spar|statement}}.
 +
}}
 +
 +
===Notes===
 
Because transfer of control is {{rlp|goto|not permitted to enter the scope}} of a variable, if a declaration statement is encountered inside the {{spar|statement}}, it has to be scoped in its own compound statement:
 
Because transfer of control is {{rlp|goto|not permitted to enter the scope}} of a variable, if a declaration statement is encountered inside the {{spar|statement}}, it has to be scoped in its own compound statement:
  
{{source|1=switch(1) {
+
{{source|1=
     case 1: int x = 0; // initialization
+
switch (1)
            std::cout << x << '\n';
+
{
            break;
+
     case 1:
     default: // compilation error: jump to default: would enter the scope of 'x'
+
        int x = 0; // initialization
            // without initializing it
+
        std::cout << x << '\n';
            std::cout << "default\n";
+
        break;
            break;
+
     default:
 +
        // compilation error: jump to default:
 +
        // would enter the scope of 'x' without initializing it
 +
        std::cout << "default\n";
 +
        break;
 
}
 
}
 
}}
 
}}
  
{{source|1=switch(1) {
+
{{source|1=
     case 1: { int x = 0;
+
switch (1)
              std::cout << x << '\n';
+
{
              break;
+
     case 1:
            } // scope of 'x' ends here
+
        {
     default: std::cout << "default\n"; // no error
+
            int x = 0;
            break;
+
            std::cout << x << '\n';
 +
            break;
 +
        } // scope of 'x' ends here
 +
     default:
 +
        std::cout << "default\n"; // no error
 +
        break;
 
}
 
}
 
}}
 
}}
  
 
===Keywords===
 
===Keywords===
 
 
{{ltt|cpp/keyword/switch}},
 
{{ltt|cpp/keyword/switch}},
 
{{ltt|cpp/keyword/case}},
 
{{ltt|cpp/keyword/case}},
Line 107: Line 146:
 
===Example===
 
===Example===
 
{{example
 
{{example
| The following code shows several usage cases of the ''switch'' statement
+
|The following code shows several usage cases of the {{c/core|switch}} statement:
| code=
+
|code=
 
#include <iostream>
 
#include <iostream>
  
 
int main()
 
int main()
 
{
 
{
     int i = 2;
+
     const int i = 2;
     switch (i) {
+
     switch (i)
         case 1: std::cout << "1";
+
    {
         case 2: std::cout << "2";  //execution starts at this case label
+
         case 1:
         case 3: std::cout << "3";
+
            std::cout << '1';
        case 4:
+
         case 2:             // execution starts at this case label
         case 5: std::cout << "45";
+
            std::cout << '2';
                break;             //execution of subsequent statements is terminated
+
         case 3:
         case 6: std::cout << "6";
+
            std::cout << '3';
 +
            [[fallthrough]]; // C++17 attribute to silent the warning on fallthrough
 +
         case 5:
 +
            std::cout << "45";
 +
            break;           // execution of subsequent statements is terminated
 +
         case 6:
 +
            std::cout << '6';
 
     }
 
     }
 
      
 
      
 
     std::cout << '\n';
 
     std::cout << '\n';
 
      
 
      
     switch (i) {
+
     switch (i)
         case 4: std::cout << "a";
+
    {
         default: std::cout << "d"; //there are no applicable constant_expressions
+
         case 4:
                                  //therefore default is executed
+
            std::cout << 'a';
 +
         default:
 +
            std::cout << 'd'; // there are no applicable constant expressions
 +
                              // therefore default is executed
 
     }
 
     }
 
+
   
 
     std::cout << '\n';
 
     std::cout << '\n';
 
+
   
     switch (i) {
+
     switch (i)
         case 4: std::cout << "a"; //nothing is executed
+
    {
 +
         case 4:
 +
            std::cout << 'a'; // nothing is executed
 
     }
 
     }
 
+
   
 
     // when enumerations are used in a switch statement, many compilers
 
     // when enumerations are used in a switch statement, many compilers
 
     // issue warnings if one of the enumerators is not handled
 
     // issue warnings if one of the enumerators is not handled
     enum color {RED, GREEN, BLUE};
+
     enum color { RED, GREEN, BLUE };
     switch(RED) {
+
     switch (RED)
         case RED:   std::cout << "red\n"; break;
+
    {
         case GREEN: std::cout << "green\n"; break;
+
         case RED:
         case BLUE: std::cout << "blue\n"; break;
+
            std::cout << "red\n";
 +
            break;
 +
         case GREEN:
 +
            std::cout << "green\n";
 +
            break;
 +
         case BLUE:
 +
            std::cout << "blue\n";
 +
            break;
 
     }
 
     }
 
+
   
 
     // the C++17 init-statement syntax can be helpful when there is
 
     // the C++17 init-statement syntax can be helpful when there is
 
     // no implicit conversion to integral or enumeration type
 
     // no implicit conversion to integral or enumeration type
     switch (Device dev = get_device(); dev.state())
+
     struct Device
 
     {
 
     {
      case SLEEP: /*...*/ break;
+
        enum State { SLEEP, READY, BAD };
      case READY: /*...*/ break;
+
        auto state() const { return m_state; }
      case BAD: /*...*/ break;
+
       
 +
        /* ... */
 +
       
 +
    private:
 +
        State m_state{};
 +
    };
 +
   
 +
    switch (auto dev = Device{}; dev.state())
 +
    {
 +
        case Device::SLEEP:
 +
            /* ... */
 +
            break;
 +
        case Device::READY:
 +
            /* ... */
 +
            break;
 +
        case Device::BAD:
 +
            /* ... */
 +
            break;
 
     }
 
     }
 
+
   
 
     // pathological examples
 
     // pathological examples
 
+
   
     // the statement doesn't have to be a compound statement
+
     // the statement does not have to be a compound statement
     switch(0)
+
     switch (0)
 
         std::cout << "this does nothing\n";
 
         std::cout << "this does nothing\n";
 
+
   
     // labels don't require a compound statement either
+
     // labels do not require a compound statement either
     switch(int n = 1)
+
     switch (int n = 1)
 
         case 0:
 
         case 0:
         case 1: std::cout << n << '\n';
+
         case 1:
 
+
            std::cout << n << '\n';
    // Duff's Device: http://en.wikipedia.org/wiki/Duff's_device
+
 
}
 
}
| output=
+
|output=
 
2345
 
2345
 
d
 
d
Line 175: Line 248:
 
1
 
1
 
}}
 
}}
 +
 +
===Defect reports===
 +
{{dr list begin}}
 +
{{dr list item|wg=cwg|dr=1767|std=C++98|before={{spar sep|condition}}s of types that are not subject to<br>integral promotion could not be promoted|after=do not promote<br>{{spar sep|condition}}s of these types}}
 +
{{dr list item|wg=cwg|dr=2629|std=C++98|before={{spar|condition}} could be a declaration of a floating-point variable|after=prohibited}}
 +
{{dr list end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc see c | c/language/switch}}
+
{{dsc see c|c/language/switch}}
 
{{dsc end}}
 
{{dsc end}}
  
 +
===External links===
 +
{{elink begin}}
 +
{{elink|num=1|{{enwiki|Duff's device|Loop unrolling using Duff's Device}}}}
 +
{{elink|num=2|{{enwiki|Coroutine#C|Duff's device can be used to implement coroutines in C/C++}}}}
 +
{{elink end}}
  
[[ar:cpp/language/switch]]
+
{{langlinks|ar|de|es|fr|it|ja|pt|ru|zh}}
[[de:cpp/language/switch]]
+
[[es:cpp/language/switch]]
+
[[fr:cpp/language/switch]]
+
[[it:cpp/language/switch]]
+
[[ja:cpp/language/switch]]
+
[[pt:cpp/language/switch]]
+
[[ru:cpp/language/switch]]
+
[[zh:cpp/language/switch]]
+

Latest revision as of 18:04, 11 August 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
switch
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Transfers control to one of several statements, depending on the value of a condition.

Contents

[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:
(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 decision varaiable of the declaration is the declared variable.

Structured binding declaration

The declaration has the following restrictions:

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 (1)
{
    case 1:
        std::cout << '1'; // prints "1",
    case 2:
        std::cout << '2'; // then prints "2"
}
switch (1)
{
    case 1:
        std::cout << '1'; // prints "1"
        break;            // and exits the switch
    case 2:
        std::cout << '2';
        break;
}

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:

switch (1)
{
    case 1:
        int x = 0; // initialization
        std::cout << x << '\n';
        break;
    default:
        // compilation error: jump to default:
        // would enter the scope of 'x' without initializing it
        std::cout << "default\n";
        break;
}
switch (1)
{
    case 1:
        {
            int x = 0;
            std::cout << x << '\n';
            break;
        } // scope of 'x' ends here
    default:
        std::cout << "default\n"; // no error
        break;
}

[edit] Keywords

switch, case, default

[edit] Example

The following code shows several usage cases of the switch statement:

#include <iostream>
 
int main()
{
    const int i = 2;
    switch (i)
    {
        case 1:
            std::cout << '1';
        case 2:              // execution starts at this case label
            std::cout << '2';
        case 3:
            std::cout << '3';
            [[fallthrough]]; // C++17 attribute to silent the warning on fallthrough
        case 5:
            std::cout << "45";
            break;           // execution of subsequent statements is terminated
        case 6:
            std::cout << '6';
    }
 
    std::cout << '\n';
 
    switch (i)
    {
        case 4:
            std::cout << 'a';
        default:
            std::cout << 'd'; // there are no applicable constant expressions 
                              // therefore default is executed
    }
 
    std::cout << '\n';
 
    switch (i)
    {
        case 4:
            std::cout << 'a'; // nothing is executed
    }
 
    // when enumerations are used in a switch statement, many compilers
    // issue warnings if one of the enumerators is not handled
    enum color { RED, GREEN, BLUE };
    switch (RED)
    {
        case RED:
            std::cout << "red\n";
            break;
        case GREEN:
            std::cout << "green\n";
            break;
        case BLUE:
            std::cout << "blue\n";
            break;
    }
 
    // the C++17 init-statement syntax can be helpful when there is
    // no implicit conversion to integral or enumeration type
    struct Device
    {
        enum State { SLEEP, READY, BAD };
        auto state() const { return m_state; }
 
        /* ... */
 
    private:
        State m_state{};
    };
 
    switch (auto dev = Device{}; dev.state())
    {
        case Device::SLEEP:
            /* ... */
            break;
        case Device::READY:
            /* ... */
            break;
        case Device::BAD:
            /* ... */
            break;
    }
 
    // pathological examples
 
    // the statement does not have to be a compound statement
    switch (0)
        std::cout << "this does nothing\n";
 
    // labels do not require a compound statement either
    switch (int n = 1)
        case 0:
        case 1:
            std::cout << n << '\n';
}

Output:

2345
d
red
1

[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 to
integral promotion could not be promoted
do not promote
condition s of these types
CWG 2629 C++98 condition could be a declaration of a floating-point variable prohibited

[edit] See also

C documentation for switch

[edit] External links

1.  Loop unrolling using Duff's Device
2.  Duff's device can be used to implement coroutines in C/C++