Difference between revisions of "cpp/language/statements"
m (Redirected page to enwiki:Rust (programming language)) |
|||
Line 1: | Line 1: | ||
− | + | {{title|Statements}} | |
+ | {{cpp/language/statements/navbar}} | ||
+ | |||
+ | Statements are fragments of the C++ program that are executed in sequence. The body of any function is a sequence of statements. For example: | ||
+ | |||
+ | {{source|1= | ||
+ | int main() | ||
+ | { | ||
+ | int n = 1; // declaration statement | ||
+ | n = n + 1; // expression statement | ||
+ | std::cout << "n = " << n << '\n'; // expression statement | ||
+ | return 0; // return statement | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | C++ includes the following types of statements: | ||
+ | @1@ labeled statements; | ||
+ | @2@ expression statements; | ||
+ | @3@ compound statements; | ||
+ | @4@ selection statements; | ||
+ | @5@ iteration statements; | ||
+ | @6@ jump statements; | ||
+ | @7@ declaration statements; | ||
+ | @8@ try blocks; | ||
+ | @9@ atomic and synchronized blocks {{mark since tm ts}}. | ||
+ | |||
+ | ===Labeled statements=== | ||
+ | A labeled statement labels a statement for control flow purposes. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|1= | ||
+ | {{spar|label statement}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | {{par begin}} | ||
+ | {{par|{{spar|label}}|the label applied to the statement (defined below)}} | ||
+ | {{par|{{spar|statement}}|the statement which the label applies to, it can be a labeled statement itself, allowing multiple labels}} | ||
+ | {{par end}} | ||
+ | |||
+ | |||
+ | {{spar|label}} is defined as | ||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|1= | ||
+ | {{spar optional|attr}} {{spar|identifier}} {{ttb|:}} | ||
+ | }} | ||
+ | {{sdsc|num=2|1= | ||
+ | {{spar optional|attr}} {{ttb|case}} {{spar|constexpr}} {{ttb|:}} | ||
+ | }} | ||
+ | {{sdsc|num=3|1= | ||
+ | {{spar optional|attr}} {{ttb|default:}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | @1@ target for {{rlp|goto}}; | ||
+ | @2@ case label in a {{rlp|switch}} statement; | ||
+ | @3@ default label in a {{rlp|switch}} statement. | ||
+ | |||
+ | {{rrev|since=c++11| | ||
+ | An {{rlp|attributes|attribute}} sequence {{spar|attr}} may appear just at the beginning of the label (in which case it applies to the label), or just before any statement itself, in which case it applies to the entire statement. | ||
+ | }} | ||
+ | |||
+ | A label with an identifier declared inside a function matches all goto statements with the same identifier in that function, in all nested blocks, before and after its own declaration. | ||
+ | |||
+ | Two labels in a function must not have the same identifier. | ||
+ | |||
+ | {{rrev|since=c++23| | ||
+ | Besides being added to a statement, labels can also be used anywhere in [[#Compound statements|compound statements]]. | ||
+ | }} | ||
+ | |||
+ | Labels are not found by {{rlp|unqualified lookup}}: a label can have the same name as any other entity in the program. | ||
+ | |||
+ | {{source|1= | ||
+ | void f() | ||
+ | { | ||
+ | { | ||
+ | goto label; // label in scope even though declared later | ||
+ | label: // label can appear at the end of a block standalone since C++23 | ||
+ | } | ||
+ | goto label; // label ignores block scope | ||
+ | } | ||
+ | |||
+ | void g() | ||
+ | { | ||
+ | goto label; // error: label not in scope in g() | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ===Expression statements=== | ||
+ | An expression statement is an expression followed by a semicolon. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|1= | ||
+ | {{spar optional|attr}} {{spar optional|expression}} {{ttb|;}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | {{par begin}} | ||
+ | {{par|{{spar|attr}}|{{mark since c++11}} optional sequence of any number of {{rlp|attributes}}}} | ||
+ | {{par|{{spar|expression}}|an {{rlp|expressions|expression}}}} | ||
+ | {{par end}} | ||
+ | |||
+ | Most statements in a typical C++ program are expression statements, such as assignments or function calls. | ||
+ | |||
+ | An expression statement without an expression is called a ''null statement''. It is often used to provide an empty body to a {{rlp|for}} or {{rlp|while}} loop. {{rev inl|until=c++23|It can also be used to carry a label in the end of a compound statement.}} | ||
+ | |||
+ | ===Compound statements=== | ||
+ | A compound statement or ''block'' groups a sequence of statements into a single statement. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|1= | ||
+ | {{spar optional|attr}} {{ttb|{}} {{spar optional|statement...}} {{spar optional|label...}}{{mark since c++23}} {{ttb|}<!-- -->}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | When one statement is expected, but multiple statements need to be executed in sequence (for example, in an {{rlp|if}} statement or a loop), a compound statement may be used: | ||
+ | |||
+ | {{source|1= | ||
+ | if (x > 5) // start of if statement | ||
+ | { // start of block | ||
+ | int n = 1; // declaration statement | ||
+ | std::cout << n; // expression statement | ||
+ | } // end of block, end of if statement | ||
+ | }} | ||
+ | |||
+ | Each compound statement introduces its own block {{rlp|scope}}; variables declared inside a block are destroyed at the closing brace in reverse order: | ||
+ | |||
+ | {{source|1= | ||
+ | int main() | ||
+ | { // start of outer block | ||
+ | { // start of inner block | ||
+ | std::ofstream f("test.txt"); // declaration statement | ||
+ | f << "abc\n"; // expression statement | ||
+ | } // end of inner block, f is flushed and closed | ||
+ | std::ifstream f("test.txt"); // declaration statement | ||
+ | std::string str; // declaration statement | ||
+ | f >> str; // expression statement | ||
+ | } // end of outer block, str is destroyed, f is closed | ||
+ | }} | ||
+ | |||
+ | {{rrev|since=c++23| | ||
+ | A [[#Labeled statements|label]] at the end of a compound statement is treated as if it were followed by a null statement. | ||
+ | }} | ||
+ | |||
+ | ===Selection statements=== | ||
+ | A selection statement chooses between one of several control flows. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|1= | ||
+ | {{spar optional|attr}} {{ttb|if constexpr}}{{mark optional}} {{ttb|(}} {{spar optional|init-statement}} {{spar|condition}} {{ttb|)}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc|num=2|1= | ||
+ | {{spar optional|attr}} {{ttb|if constexpr}}{{mark optional}} {{ttb|(}} {{spar optional|init-statement}} {{spar|condition}} {{ttb|)}} {{spar|statement}} {{ttb|else}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc|num=3|1= | ||
+ | {{spar optional|attr}} {{ttb|switch (}} {{spar optional|init-statement}} {{spar|condition}} {{ttb|)}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc|num=4|notes={{mark since c++23}}|1= | ||
+ | {{spar optional|attr}} {{ttb|if !}}{{mark optional}} {{ttb|consteval}} {{spar|compound-statement}} | ||
+ | }} | ||
+ | {{sdsc|num=5|notes={{mark since c++23}}|1= | ||
+ | {{spar optional|attr}} {{ttb|if !}}{{mark optional}} {{ttb|consteval}} {{spar|compound-statement}} {{ttb|else}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | @1@ {{rlp|if}} statement; | ||
+ | @2@ {{rlp|if}} statement with an else clause; | ||
+ | @3@ {{rlp|switch}} statement; | ||
+ | @4@ {{rlp|if#Consteval if|consteval if}} statement; | ||
+ | @5@ {{rlp|if#Consteval if|consteval if}} statement with an else clause. | ||
+ | |||
+ | ===Iteration statements=== | ||
+ | An iteration statement repeatedly executes some code. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|1= | ||
+ | {{spar optional|attr}} {{ttb|while (}} {{spar|condition}} {{ttb|)}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc|num=2|1= | ||
+ | {{spar optional|attr}} {{ttb|do}} {{spar|statement}} {{ttb|while (}} {{spar|expression}} {{ttb|)}} {{ttb|;}} | ||
+ | }} | ||
+ | {{sdsc|num=3|1= | ||
+ | {{spar optional|attr}} {{ttb|for (}} {{spar optional|init-statement condition}} {{ttb|;}} {{spar optional|expression}} {{ttb|)}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc|num=4|notes={{mark since c++11}}|1= | ||
+ | {{spar optional|attr}} {{ttb|for (}} {{spar optional|init-statement}}{{mark since c++20}} {{spar|for-range-decl}} {{ttb|:}} {{spar|for-range-init}} {{ttb|)}} {{spar|statement}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | @1@ {{rlp|while}} loop; | ||
+ | @2@ {{rlp|do|do-while}} loop; | ||
+ | @3@ {{rlp|for|for}} loop; | ||
+ | @4@ {{rlp|range-for|range for}} loop. | ||
+ | |||
+ | ===Jump statements=== | ||
+ | A jump statement unconditionally transfers control flow. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|1= | ||
+ | {{spar optional|attr}} {{ttb|break;}} | ||
+ | }} | ||
+ | {{sdsc|num=2|1= | ||
+ | {{spar optional|attr}} {{ttb|continue;}} | ||
+ | }} | ||
+ | {{sdsc|num=3|1= | ||
+ | {{spar optional|attr}} {{ttb|return}} {{spar optional|expression}} {{ttb|;}} | ||
+ | }} | ||
+ | {{sdsc|num=4|notes={{mark since c++11}}|1= | ||
+ | {{spar optional|attr}} {{ttb|return}} {{spar|braced-init-list}} {{ttb|;}} | ||
+ | }} | ||
+ | {{sdsc|num=5|1= | ||
+ | {{spar optional|attr}} {{ttb|goto}} {{spar|identifier}} {{ttb|;}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | @1@ {{rlp|break}} statement; | ||
+ | @2@ {{rlp|continue}} statement; | ||
+ | @3@ {{rlp|return}} statement with an optional expression; | ||
+ | @4@ {{rlp|return}} statement using {{rlp|list initialization}}; | ||
+ | @5@ {{rlp|goto}} statement. | ||
+ | |||
+ | Note: for all jump statements, transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of objects with automatic storage duration that are in scope at the point transferred from but not at the point transferred to. If multiple objects were initialized, the order of destruction is the opposite of the order of initialization. | ||
+ | |||
+ | ===Declaration statements=== | ||
+ | A declaration statement introduces one or more identifiers into a block. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|1= | ||
+ | {{spar|block-declaration}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | @1@ see {{rlp|declarations|Declarations}} and {{rlp|initialization|Initialization}} for details. | ||
+ | |||
+ | ===Try blocks=== | ||
+ | A try block catches exceptions thrown when executing other statements. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|1= | ||
+ | {{spar optional|attr}} {{ttb|try}} {{spar|compound-statement handler-sequence}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | |||
+ | @1@ see {{rlp|try_catch|try/catch}} for details. | ||
+ | |||
+ | {{rev begin}} | ||
+ | {{rev|since=tm_ts| | ||
+ | ===Atomic and synchronized blocks=== | ||
+ | An atomic and synchronized block provides {{rlp|transactional memory}}. | ||
+ | |||
+ | {{sdsc begin}} | ||
+ | {{sdsc|num=1|notes={{mark since tm ts}}|1= | ||
+ | {{ttb|synchronized}} {{spar|compound-statement}} | ||
+ | }} | ||
+ | {{sdsc|num=2|notes={{mark since tm ts}}|1= | ||
+ | {{ttb|atomic_noexcept}} {{spar|compound-statement}} | ||
+ | }} | ||
+ | {{sdsc|num=3|notes={{mark since tm ts}}|1= | ||
+ | {{ttb|atomic_cancel}} {{spar|compound-statement}} | ||
+ | }} | ||
+ | {{sdsc|num=4|notes={{mark since tm ts}}|1= | ||
+ | {{ttb|atomic_commit}} {{spar|compound-statement}} | ||
+ | }} | ||
+ | {{sdsc end}} | ||
+ | @1@ {{rlp|transactional memory#Synchronized blocks|synchronized block}}, executed in single total order with all synchronized blocks; | ||
+ | @2@ {{rlp|transactional memory#Atomic blocks|atomic block}} that aborts on exceptions; | ||
+ | @3@ {{rlp|transactional memory#Atomic blocks|atomic block}} that rolls back on exceptions; | ||
+ | @4@ {{rlp|transactional memory#Atomic blocks|atomic block}} that commits on exceptions. | ||
+ | }} | ||
+ | {{rev end}} | ||
+ | |||
+ | ===See also=== | ||
+ | {{dsc begin}} | ||
+ | {{dsc see c|c/language/statements|Statements|nomono=true}} | ||
+ | {{dsc end}} | ||
+ | |||
+ | {{langlinks|es|ja|ru|zh}} |
Revision as of 13:03, 30 July 2023
Statements are fragments of the C++ program that are executed in sequence. The body of any function is a sequence of statements. For example:
int main() { int n = 1; // declaration statement n = n + 1; // expression statement std::cout << "n = " << n << '\n'; // expression statement return 0; // return statement }
C++ includes the following types of statements:
Contents |
Labeled statements
A labeled statement labels a statement for control flow purposes.
label statement | |||||||||
label | - | the label applied to the statement (defined below) |
statement | - | the statement which the label applies to, it can be a labeled statement itself, allowing multiple labels |
label is defined as
attr (optional) identifier :
|
(1) | ||||||||
attr (optional) case constexpr :
|
(2) | ||||||||
attr (optional) default:
|
(3) | ||||||||
An attribute sequence attr may appear just at the beginning of the label (in which case it applies to the label), or just before any statement itself, in which case it applies to the entire statement. |
(since C++11) |
A label with an identifier declared inside a function matches all goto statements with the same identifier in that function, in all nested blocks, before and after its own declaration.
Two labels in a function must not have the same identifier.
Besides being added to a statement, labels can also be used anywhere in compound statements. |
(since C++23) |
Labels are not found by unqualified lookup: a label can have the same name as any other entity in the program.
void f() { { goto label; // label in scope even though declared later label: // label can appear at the end of a block standalone since C++23 } goto label; // label ignores block scope } void g() { goto label; // error: label not in scope in g() }
Expression statements
An expression statement is an expression followed by a semicolon.
attr (optional) expression (optional) ;
|
|||||||||
attr | - | (since C++11) optional sequence of any number of attributes |
expression | - | an expression |
Most statements in a typical C++ program are expression statements, such as assignments or function calls.
An expression statement without an expression is called a null statement. It is often used to provide an empty body to a for or while loop. It can also be used to carry a label in the end of a compound statement.(until C++23)
Compound statements
A compound statement or block groups a sequence of statements into a single statement.
attr (optional) { statement... (optional) label... (optional)(since C++23) }
|
|||||||||
When one statement is expected, but multiple statements need to be executed in sequence (for example, in an if statement or a loop), a compound statement may be used:
if (x > 5) // start of if statement { // start of block int n = 1; // declaration statement std::cout << n; // expression statement } // end of block, end of if statement
Each compound statement introduces its own block scope; variables declared inside a block are destroyed at the closing brace in reverse order:
int main() { // start of outer block { // start of inner block std::ofstream f("test.txt"); // declaration statement f << "abc\n"; // expression statement } // end of inner block, f is flushed and closed std::ifstream f("test.txt"); // declaration statement std::string str; // declaration statement f >> str; // expression statement } // end of outer block, str is destroyed, f is closed
A label at the end of a compound statement is treated as if it were followed by a null statement. |
(since C++23) |
Selection statements
A selection statement chooses between one of several control flows.
attr (optional) if constexpr (optional) ( init-statement (optional) condition ) statement
|
(1) | ||||||||
attr (optional) if constexpr (optional) ( init-statement (optional) condition ) statement else statement
|
(2) | ||||||||
attr (optional) switch ( init-statement (optional) condition ) statement
|
(3) | ||||||||
attr (optional) if ! (optional) consteval compound-statement
|
(4) | (since C++23) | |||||||
attr (optional) if ! (optional) consteval compound-statement else statement
|
(5) | (since C++23) | |||||||
Iteration statements
An iteration statement repeatedly executes some code.
attr (optional) while ( condition ) statement
|
(1) | ||||||||
attr (optional) do statement while ( expression ) ;
|
(2) | ||||||||
attr (optional) for ( init-statement condition (optional) ; expression (optional) ) statement
|
(3) | ||||||||
attr (optional) for ( init-statement (optional)(since C++20) for-range-decl : for-range-init ) statement
|
(4) | (since C++11) | |||||||
Jump statements
A jump statement unconditionally transfers control flow.
attr (optional) break;
|
(1) | ||||||||
attr (optional) continue;
|
(2) | ||||||||
attr (optional) return expression (optional) ;
|
(3) | ||||||||
attr (optional) return braced-init-list ;
|
(4) | (since C++11) | |||||||
attr (optional) goto identifier ;
|
(5) | ||||||||
Note: for all jump statements, transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of objects with automatic storage duration that are in scope at the point transferred from but not at the point transferred to. If multiple objects were initialized, the order of destruction is the opposite of the order of initialization.
Declaration statements
A declaration statement introduces one or more identifiers into a block.
block-declaration | (1) | ||||||||
Try blocks
A try block catches exceptions thrown when executing other statements.
attr (optional) try compound-statement handler-sequence
|
(1) | ||||||||
Atomic and synchronized blocksAn atomic and synchronized block provides transactional memory.
1) synchronized block, executed in single total order with all synchronized blocks;
2) atomic block that aborts on exceptions;
3) atomic block that rolls back on exceptions;
4) atomic block that commits on exceptions.
|
(TM TS) |
See also
C documentation for Statements
|