Skip to content

Commit

Permalink
Tweak formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin Robertson committed Apr 28, 2020
1 parent f8ab241 commit b95d987
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 40 deletions.
42 changes: 24 additions & 18 deletions docs/c-language/switch-statement-c.md
Expand Up @@ -8,20 +8,26 @@ no-loc: [ switch, case, default, break ]
---
# `switch` Statement (C)

The **switch** and **case** statements help control complex conditional and branching operations. The **switch** statement transfers control to a statement within its body.
The __`switch`__ and __`case`__ statements help control complex conditional and branching operations. The __`switch`__ statement transfers control to a statement within its body.

## Syntax

> *selection-statement*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`switch (`__ &nbsp; *expression* &nbsp; __`)`__ &nbsp; *statement*
> *`selection-statement`*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`switch (`__&nbsp;*`expression`* &nbsp;__`)`__&nbsp;*`statement`*
> *labeled-statement*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`case`__ &nbsp; *constant-expression* &nbsp; __`:`__ &nbsp; *statement*<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`default :`__ &nbsp; *statement*
> *`labeled-statement`*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`case`__&nbsp;*`constant-expression`*&nbsp;__`:`__&nbsp;*`statement`*<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`default`__&nbsp;__`:`__&nbsp;*`statement`*
Control passes to the **case** statement whose *constant-expression* matches the value of **`switch (`** *expression* **`)`**. The **switch** statement can include any number of **case** instances. However, no two case constants within the same **switch** statement can have the same value. Execution of the statement body begins at the selected statement. It proceeds until the end of the body, or until a **break** statement transfers control out of the body.
## Remarks

Use of the **switch** statement usually looks something like this:
A __`switch`__ statement causes control to transfer to one *`labeled-statement`* in its statement body, depending on the value of *`expression`*.

The values of *`expression`* and each *`constant-expression`* must have an integral type. A *`constant-expression`* must have an unambiguous constant integral value at compile time.

Control passes to the **`case`** statement whose *`constant-expression`* value matches the value of *`expression`*. The __`switch`__ statement can include any number of __`case`__ instances. However, no two *`constant-expression`* values within the same __`switch`__ statement can have the same value. Execution of the __`switch`__ statement body begins at the first statement in or after the matching *`labeled-statement`*. Execution proceeds until the end of the body, or until a __`break`__ statement transfers control out of the body.

Use of the __`switch`__ statement usually looks something like this:

```C
switch ( expression )
Expand All @@ -38,18 +44,18 @@ switch ( expression )
}
```

You can use the **break** statement to end processing of a particular labeled statement within the **switch** statement. It branches to the end of the **switch** statement. Without **break**, the program continues to the next labeled statement, executing the statements until a **break** or the end of the statement is reached. This continuation may be desirable in some situations.
You can use the __`break`__ statement to end processing of a particular labeled statement within the __`switch`__ statement. It branches to the end of the __`switch`__ statement. Without __`break`__, the program continues to the next labeled statement, executing the statements until a __`break`__ or the end of the statement is reached. This continuation may be desirable in some situations.

The **default** statement is executed if no **case** *constant-expression* is equal to the value of **switch (** *expression* **)**. If there's no **default** statement, and no **case** match is found, none of the statements in the **switch** body get executed. There can be at most one **default** statement. The **default** statement doesn't have to come at the end. It may appear anywhere in the body of the **switch** statement. A **case** or **default** label can only appear inside a **switch** statement.
The __`default`__ statement is executed if no __`case`__ *`constant-expression`* value is equal to the value of *`expression`*. If there's no __`default`__ statement, and no __`case`__ match is found, none of the statements in the __`switch`__ body get executed. There can be at most one __`default`__ statement. The __`default`__ statement doesn't have to come at the end. It may appear anywhere in the body of the __`switch`__ statement. A __`case`__ or __`default`__ label can only appear inside a __`switch`__ statement.

The type of **switch** *expression* and **case** *constant-expression* must be integral. The value of each **case** *constant-expression* must be unique within the statement body.
The type of __`switch`__ *`expression`* and __`case`__ *`constant-expression`* must be integral. The value of each __`case`__ *`constant-expression`* must be unique within the statement body.

The **case** and **default** labels of the **switch** statement's body are significant only in the initial test that determines where execution starts in the statement body. **switch** statements can be nested. Any static variables are initialized before executing into any **switch** statements.
The __`case`__ and __`default`__ labels of the __`switch`__ statement's body are significant only in the initial test that determines where execution starts in the statement body. __`switch`__ statements can be nested. Any static variables are initialized before executing into any __`switch`__ statements.

> [!NOTE]
> Declarations can appear at the head of the compound statement forming the **switch** body, but initializations included in the declarations are not performed. The **switch** statement transfers control directly to an executable statement within the body, bypassing the lines that contain initializations.
> Declarations can appear at the head of the compound statement forming the __`switch`__ body, but initializations included in the declarations are not performed. The __`switch`__ statement transfers control directly to an executable statement within the body, bypassing the lines that contain initializations.
The following examples illustrate **switch** statements:
The following examples illustrate __`switch`__ statements:

```C
switch( c )
Expand All @@ -63,7 +69,7 @@ switch( c )
}
```

All three statements of the **switch** body in this example are executed if `c` is equal to `'A'`, since no **break** statement appears before the following case. Execution control is transferred to the first statement (`capital_a++;`) and continues in order through the rest of the body. If `c` is equal to `'a'`, `letter_a` and `total` are incremented. Only `total` is incremented when `c` doesn't equal `'A'` or `'a'`.
All three statements of the __`switch`__ body in this example are executed if `c` is equal to `'A'`, since no __`break`__ statement appears before the following __`case`__. Execution control is transferred to the first statement (`capital_a++;`) and continues in order through the rest of the body. If `c` is equal to `'a'`, `letter_a` and `total` are incremented. Only `total` is incremented when `c` doesn't equal `'A'` or `'a'`.

```C
switch( i )
Expand All @@ -80,9 +86,9 @@ switch( i )
}
```

In this example, a **break** statement follows each statement of the **switch** body. The **break** statement forces an exit from the statement body after one statement is executed. If `i` is equal to -1, only `n` is incremented. The **break** following the statement `n++;` causes execution control to pass out of the statement body, bypassing the remaining statements. Similarly, if `i` is equal to 0, only `z` is incremented; if `i` is equal to 1, only `p` is incremented. The final **break** statement isn't strictly necessary, since control passes out of the body at the end of the compound statement. It's included for consistency.
In this example, a __`break`__ statement follows each statement of the __`switch`__ body. The __`break`__ statement forces an exit from the statement body after one statement is executed. If `i` is equal to -1, only `n` is incremented. The __`break`__ following the statement `n++;` causes execution control to pass out of the statement body, bypassing the remaining statements. Similarly, if `i` is equal to 0, only `z` is incremented; if `i` is equal to 1, only `p` is incremented. The final __`break`__ statement isn't strictly necessary, since control passes out of the body at the end of the compound statement. It's included for consistency.

A single statement can carry multiple **case** labels, as the following example shows:
A single statement can carry multiple __`case`__ labels, as the following example shows:

```C
switch( c )
Expand All @@ -100,7 +106,7 @@ In this example, if *constant-expression* equals any letter between `'a'` and `'

### Microsoft-specific

Microsoft C doesn't limit the number of case values in a **switch** statement. The number is limited only by the available memory. ANSI C requires at least 257 case labels be allowed in a **switch** statement.
Microsoft C doesn't limit the number of __`case`__ values in a __`switch`__ statement. The number is limited only by the available memory. ANSI C requires at least 257 __`case`__ labels be allowed in a __`switch`__ statement.

The default for Microsoft C is that the Microsoft extensions are enabled. Use the [/Za](../build/reference/za-ze-disable-language-extensions.md) compiler option to disable these extensions.

Expand Down
53 changes: 31 additions & 22 deletions docs/cpp/switch-statement-cpp.md
Expand Up @@ -4,38 +4,49 @@ description: "Reference to the Standard C++ switch statement in Microsoft Visual
ms.date: "04/15/2020"
f1_keywords: ["default_cpp", "switch_cpp", "case_cpp"]
helpviewer_keywords: ["switch keyword [C++]", "case keyword [C++], in switch statements", "default keyword [C++]"]
no-loc: [switch, case, default, break, while]
no-loc: [switch, case, default, break, while, C++, opt]
ms.assetid: 6c3f3ed3-5593-463c-8f4b-b33742b455c6
---
# switch statement (C++)
# `switch` statement (C++)

Allows selection among multiple sections of code, depending on the value of an integral expression.

## Syntax

> __`switch (`__ &nbsp; \[*initialization* __`;`__\] &nbsp; *expression* &nbsp; __`)`__ <br/>
> __`{`__\
> &nbsp;&nbsp;&nbsp;&nbsp; __`case`__ &nbsp; *constant-expression* &nbsp; __`:`__ &nbsp; *statement* <br/>
> &nbsp;&nbsp;&nbsp;&nbsp; \[__`default :`__ &nbsp; *statement*\] <br/>
> __`}`__
> *`selection-statement`*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`switch`__&nbsp;__`(`__&nbsp;*`init-statement`*<sub>opt</sub><sup>C++17</sup>&nbsp;*`condition`*&nbsp;__`)`__&nbsp;*`statement`*
> *`init-statement`*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; *`expression-statement`*<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; *`simple-declaration`*
> *`condition`*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; *`expression`*<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; *`attribute-specifier-seq`*<sub>opt</sub>&nbsp;*`decl-specifier-seq`*&nbsp;*`declarator`*&nbsp;*`brace-or-equal-initializer`*
> *`labeled-statement`*:<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`case`__&nbsp;*`constant-expression`*&nbsp;__`:`__&nbsp;*`statement`*<br/>
> &nbsp;&nbsp;&nbsp;&nbsp; __`default`__&nbsp;__`:`__&nbsp;*`statement`*
## Remarks

The *expression* must have an integral type, or be a class type that has an unambiguous conversion to integral type. Integral promotion takes place as described in [Standard conversions](standard-conversions.md).
A __`switch`__ statement causes control to transfer to one *`labeled-statement`* in its statement body, depending on the value of *`condition`*.

The **switch** statement body consists of a series of **case** labels and an optional **default** label. Collectively, the statements that follow the labels are called *labeled* statements. The labeled statements aren't syntactic requirements, but the **switch** statement is meaningless without them. No two constant expressions in **case** statements may evaluate to the same value. The **default** label may appear only once. The **default** statement is often placed at the end, but it can appear anywhere in the body of the **switch** statement. A **case** or **default** label can only appear inside a **switch** statement.
The *`condition`* must have an integral type, or be a class type that has an unambiguous conversion to integral type. Integral promotion takes place as described in [Standard conversions](standard-conversions.md).

The *constant-expression* in each **case** label is converted to the type of *expression*. Then, it's compared with *expression* for equality. Control passes to the statement whose **case** *constant-expression* matches the value of *expression*. The resulting behavior is shown in the following table.
The __`switch`__ statement body consists of a series of __`case`__ labels and an optional __`default`__ label. A *`labeled-statement`* is one of these labels and the statements that follow. The labeled statements aren't syntactic requirements, but the __`switch`__ statement is meaningless without them. No two *`constant-expression`* values in __`case`__ statements may evaluate to the same value. The __`default`__ label may appear only once. The __`default`__ statement is often placed at the end, but it can appear anywhere in the __`switch`__ statement body. A __`case`__ or __`default`__ label can only appear inside a __`switch`__ statement.

### Switch statement behavior
The *`constant-expression`* in each __`case`__ label is converted to a constant value that's the same type as *`condition`*. Then, it's compared with *`condition`* for equality. Control passes to the first statement after the __`case`__ *`constant-expression`* value that matches the value of *`condition`*. The resulting behavior is shown in the following table.

### `switch` statement behavior

| Condition | Action |
|--|--|
| Converted value matches that of the promoted controlling expression. | Control is transferred to the statement following that label. |
| None of the constants match the constants in the **case** labels; a **default** label is present. | Control is transferred to the **default** label. |
| None of the constants match the constants in the **case** labels; no **default** label is present. | Control is transferred to the statement after the **switch** statement. |
| None of the constants match the constants in the __`case`__ labels; a __`default`__ label is present. | Control is transferred to the __`default`__ label. |
| None of the constants match the constants in the __`case`__ labels; no __`default`__ label is present. | Control is transferred to the statement after the __`switch`__ statement. |

If a matching expression is found, execution can continue through later **case** or **default** labels. The [`break`](../cpp/break-statement-cpp.md) statement is used to stop execution and transfer control to the statement after the **switch** statement. Without a **break** statement, every statement from the matched **case** label to the end of the **switch**, including the **default**, is executed. For example:
If a matching expression is found, execution can continue through later __`case`__ or __`default`__ labels. The [`break`](../cpp/break-statement-cpp.md) statement is used to stop execution and transfer control to the statement after the __`switch`__ statement. Without a __`break`__ statement, every statement from the matched __`case`__ label to the end of the __`switch`__, including the __`default`__, is executed. For example:

```cpp
// switch_statement1.cpp
Expand Down Expand Up @@ -66,9 +77,9 @@ int main() {
}
```

In the above example, `uppercase_A` is incremented if `c` is an uppercase `'A'`. The **break** statement after `uppercase_A++` terminates execution of the **switch** statement body and control passes to the **while** loop. Without the **break** statement, execution would "fall through" to the next labeled statement, so that `lowercase_a` and `other` would also be incremented. A similar purpose is served by the **break** statement for `case 'a'`. If `c` is a lowercase `'a'`, `lowercase_a` is incremented and the **break** statement terminates the **switch** statement body. If `c` isn't an `'a'` or `'A'`, the **default** statement is executed.
In the above example, `uppercase_A` is incremented if `c` is an uppercase `'A'`. The __`break`__ statement after `uppercase_A++` terminates execution of the __`switch`__ statement body and control passes to the __`while`__ loop. Without the __`break`__ statement, execution would "fall through" to the next labeled statement, so that `lowercase_a` and `other` would also be incremented. A similar purpose is served by the __`break`__ statement for `case 'a'`. If `c` is a lowercase `'a'`, `lowercase_a` is incremented and the __`break`__ statement terminates the __`switch`__ statement body. If `c` isn't an `'a'` or `'A'`, the __`default`__ statement is executed.

**Visual Studio 2017 and later:** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)) The `[[fallthrough]]` attribute is specified in the C++17 standard. You can use it in a **switch** statement. It's a hint to the compiler, or anyone who reads the code, that fall-through behavior is intentional. The Microsoft C++ compiler currently doesn't warn on fallthrough behavior, so this attribute has no effect on compiler behavior. In the example, the attribute gets applied to an empty statement within the unterminated labeled statement. In other words, the semicolon is necessary.
**Visual Studio 2017 and later:** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)) The `[[fallthrough]]` attribute is specified in the C++17 standard. You can use it in a __`switch`__ statement. It's a hint to the compiler, or anyone who reads the code, that fall-through behavior is intentional. The Microsoft C++ compiler currently doesn't warn on fallthrough behavior, so this attribute has no effect on compiler behavior. In the example, the attribute gets applied to an empty statement within the unterminated labeled statement. In other words, the semicolon is necessary.

```cpp
int main()
Expand Down Expand Up @@ -96,7 +107,7 @@ int main()
}
```

**Visual Studio 2017 version 15.3 and later** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)). A switch statement may have an *initialization* clause. It introduces and initializes a variable whose scope is limited to the block of the switch statement:
**Visual Studio 2017 version 15.3 and later** (available with [/std:c++17](../build/reference/std-specify-language-standard-version.md)). A __`switch`__ statement may have an *`init-statement`* clause, which ends with a semicolon. It introduces and initializes a variable whose scope is limited to the block of the __`switch`__ statement:

```cpp
switch (Gadget gadget(args); auto s = gadget.get_status())
Expand All @@ -109,7 +120,7 @@ int main()
};
```
An inner block of a **switch** statement can contain definitions with initializations as long as they're *reachable*, that is, not bypassed by all possible execution paths. Names introduced using these declarations have local scope. For example:
An inner block of a __`switch`__ statement can contain definitions with initializers as long as they're *reachable*, that is, not bypassed by all possible execution paths. Names introduced using these declarations have local scope. For example:
```cpp
// switch_statement2.cpp
Expand Down Expand Up @@ -144,13 +155,11 @@ int main(int argc, char *argv[])
}
```

A **switch** statement can be nested. When nested, the **case** or **default** labels associate with the closest **switch** statement that encloses them.
A __`switch`__ statement can be nested. When nested, the __`case`__ or __`default`__ labels associate with the closest __`switch`__ statement that encloses them.

### Microsoft-specific behavior

Microsoft C doesn't limit the number of **case** values in a **switch** statement. The number is limited only by the available memory. ANSI C requires at least 257 **case** labels be allowed in a **switch** statement.

The default for Microsoft C is that the Microsoft extensions are enabled. Use the [/Za](../build/reference/za-ze-disable-language-extensions.md) compiler option to disable these extensions.
Microsoft C++ doesn't limit the number of __`case`__ values in a __`switch`__ statement. The number is limited only by the available memory.

## See also

Expand Down

0 comments on commit b95d987

Please sign in to comment.