Files
cppdraft_translate/cppdraft/stmt/jump.md
2025-10-25 03:02:53 +03:00

244 lines
13 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[stmt.jump]
# 8 Statements [[stmt]](./#stmt)
## 8.8 Jump statements [stmt.jump]
### [8.8.1](#general) General [[stmt.jump.general]](stmt.jump.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L988)
Jump statements unconditionally transfer control[.](#general-1.sentence-1)
[jump-statement:](#nt:jump-statement "8.8.1General[stmt.jump.general]")
break ;
continue ;
return [*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1General[dcl.init.general]")opt ;
[*coroutine-return-statement*](#nt:coroutine-return-statement "8.8.5The co_­return statement[stmt.return.coroutine]")
goto [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") ;
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1007)
[*Note [1](#general-note-1)*:
On exit from a scope (however accomplished), objects with [automatic storage
duration](basic.stc.auto "6.8.6.4Automatic storage duration[basic.stc.auto]") that have been constructed in that scope are destroyed
in the reverse order of their construction ([[stmt.dcl]](stmt.dcl "8.10Declaration statement"))[.](#general-2.sentence-1)
For temporaries, see [[class.temporary]](class.temporary "6.8.7Temporary objects")[.](#general-2.sentence-2)
However, the program can be terminated (by callingstd::exit() orstd::abort() ([[support.start.term]](support.start.term "17.5Startup and termination")), for example) without
destroying objects with automatic storage duration[.](#general-2.sentence-3)
— *end note*]
[*Note [2](#general-note-2)*:
A suspension of a coroutine ([[expr.await]](expr.await "7.6.2.4Await")) is not considered to be an exit from a scope[.](#general-2.sentence-4)
— *end note*]
### [8.8.2](#stmt.break) The break statement [[stmt.break]](stmt.break)
[1](#stmt.break-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1031)
A break statement shall be enclosed by ([[stmt.pre]](stmt.pre "8.1Preamble"))an [*iteration-statement*](stmt.iter.general#nt:iteration-statement "8.6.1General[stmt.iter.general]") ([[stmt.iter]](stmt.iter "8.6Iteration statements")),
an [*expansion-statement*](stmt.expand#nt:expansion-statement "8.7Expansion statements[stmt.expand]") ([[stmt.expand]](stmt.expand "8.7Expansion statements")), or
a switch statement ([[stmt.switch]](stmt.switch "8.5.3The switch statement"))[.](#stmt.break-1.sentence-1)
The break statement causes
termination of the innermost such enclosing statement;
control passes to the statement following the
terminated statement, if any[.](#stmt.break-1.sentence-2)
### [8.8.3](#stmt.cont) The continue statement [[stmt.cont]](stmt.cont)
[1](#stmt.cont-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1046)
A continue statement shall be enclosed by ([[stmt.pre]](stmt.pre "8.1Preamble"))an [*iteration-statement*](stmt.iter.general#nt:iteration-statement "8.6.1General[stmt.iter.general]") or an [*expansion-statement*](stmt.expand#nt:expansion-statement "8.7Expansion statements[stmt.expand]")[.](#stmt.cont-1.sentence-1)
If the innermost enclosing such statement X is an [*iteration-statement*](stmt.iter.general#nt:iteration-statement "8.6.1General[stmt.iter.general]") ([[stmt.iter]](stmt.iter "8.6Iteration statements")),
the continue statement
causes control to pass to the end of the [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]") or [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of X[.](#stmt.cont-1.sentence-2)
Otherwise, control passes to the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of the current Si ([[stmt.expand]](stmt.expand "8.7Expansion statements"))[.](#stmt.cont-1.sentence-3)
### [8.8.4](#stmt.return) The return statement [[stmt.return]](stmt.return)
[1](#stmt.return-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1063)
A function returns control to its caller by the return statement[.](#stmt.return-1.sentence-1)
[2](#stmt.return-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1066)
The [*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1General[dcl.init.general]") of a return statement is called its operand[.](#stmt.return-2.sentence-1)
A return statement with
no operand shall be used only in a function whose return type iscv void, a constructor ([[class.ctor]](class.ctor "11.4.5Constructors")), or a
destructor ([[class.dtor]](class.dtor "11.4.7Destructors"))[.](#stmt.return-2.sentence-2)
A return statement with an operand of type void shall be used only
in a function that has a cv void return type[.](#stmt.return-2.sentence-3)
A return statement with any other operand shall be used only
in a function that has a return type other than cv void;the return statement initializes the
returned reference or prvalue result object
of the (explicit or implicit) function call
by [copy-initialization](dcl.init#def:copy-initialization "9.5Initializers[dcl.init]") from the operand[.](#stmt.return-2.sentence-4)
[*Note [1](#stmt.return-note-1)*:
A constructor or destructor does not have a return type[.](#stmt.return-2.sentence-5)
— *end note*]
[*Note [2](#stmt.return-note-2)*:
A return statement can involve
an invocation of a constructor to perform a copy or move of the operand
if it is not a prvalue or if its type differs from the return type of the function[.](#stmt.return-2.sentence-6)
A copy operation associated with a return statement can be elided or
converted to a move operation if an automatic storage duration variable is returned ([[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision"))[.](#stmt.return-2.sentence-7)
— *end note*]
[3](#stmt.return-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1094)
The destructor for the result object
is potentially invoked ([[class.dtor]](class.dtor "11.4.7Destructors"), [[except.ctor]](except.ctor "14.3Stack unwinding"))[.](#stmt.return-3.sentence-1)
[*Example [1](#stmt.return-example-1)*: class A {~A() {}};
A f() { return A(); } // error: destructor of A is private (even though it is never invoked) — *end example*]
[4](#stmt.return-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1106)
Flowing off the end of
a constructor,
a destructor, or
a non-coroutine function with a cv void return type is
equivalent to a return with no operand[.](#stmt.return-4.sentence-1)
Otherwise, flowing off the end of a function
that is neither main ([[basic.start.main]](basic.start.main "6.10.3.1main function")) nor a coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))
results in undefined behavior[.](#stmt.return-4.sentence-2)
[5](#stmt.return-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1116)
The copy-initialization of the result of the call is sequenced before the
destruction of temporaries at the end of the full-expression established
by the operand of the return statement, which, in turn, is sequenced
before the destruction of local variables ([stmt.jump]) of the block
enclosing the return statement[.](#stmt.return-5.sentence-1)
[*Note [3](#stmt.return-note-3)*:
These operations
are sequenced before the destruction of local variables
in each remaining enclosing block of the function ([[stmt.dcl]](stmt.dcl "8.10Declaration statement")),
which, in turn,
is sequenced before the evaluation of
postcondition assertions of the function ([[dcl.contract.func]](dcl.contract.func "9.4.1General")),
which, in turn,
is sequenced before the destruction of function parameters ([[expr.call]](expr.call "7.6.1.3Function call"))[.](#stmt.return-5.sentence-2)
— *end note*]
[6](#stmt.return-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1133)
In a function whose return type is a reference,
other than an invented function for std::is_convertible ([[meta.rel]](meta.rel "21.3.8Relationships between types")),
a return statement that binds the returned reference to
a temporary expression ([[class.temporary]](class.temporary "6.8.7Temporary objects")) is ill-formed[.](#stmt.return-6.sentence-1)
[*Example [2](#stmt.return-example-2)*: auto&& f1() {return 42; // ill-formed}const double& f2() {static int x = 42; return x; // ill-formed}auto&& id(auto&& r) {return static_cast<decltype(r)&&>(r);}auto&& f3() {return id(42); // OK, but probably a bug} — *end example*]
### [8.8.5](#stmt.return.coroutine) The co_return statement [[stmt.return.coroutine]](stmt.return.coroutine)
[coroutine-return-statement:](#nt:coroutine-return-statement "8.8.5The co_­return statement[stmt.return.coroutine]")
co_return [*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1General[dcl.init.general]")opt ;
[1](#stmt.return.coroutine-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1165)
A co_return statement transfers control to
the caller or resumer of a coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))[.](#stmt.return.coroutine-1.sentence-1)
A coroutine shall not enclose
a return statement ([[stmt.return]](#stmt.return "8.8.4The return statement"))[.](#stmt.return.coroutine-1.sentence-2)
[*Note [1](#stmt.return.coroutine-note-1)*:
For this determination, it is irrelevant whether the return statement
is enclosed by a discarded statement ([[stmt.if]](stmt.if "8.5.2The if statement"))[.](#stmt.return.coroutine-1.sentence-3)
— *end note*]
[2](#stmt.return.coroutine-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1175)
The [*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1General[dcl.init.general]") of a co_return statement is
called its operand[.](#stmt.return.coroutine-2.sentence-1)
Let *p* be an lvalue naming the coroutine
promise object ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))[.](#stmt.return.coroutine-2.sentence-2)
A co_return statement is equivalent to:
{ S; goto *final-suspend*; }
where *final-suspend* is the exposition-only label
defined in [[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions") and *S* is defined as follows:
- [(2.1)](#stmt.return.coroutine-2.1)
If the operand is a [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]") or an expression of non-void type,*S* is *p*.return_value([*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1General[dcl.init.general]"))[.](#stmt.return.coroutine-2.1.sentence-1)
The expression *S* shall be a prvalue of type void[.](#stmt.return.coroutine-2.1.sentence-2)
- [(2.2)](#stmt.return.coroutine-2.2)
Otherwise,*S* is the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") { [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]")opt ; *p*.return_void(); }[.](#stmt.return.coroutine-2.2.sentence-1)
The expression *p*.return_void() shall be a prvalue of type void[.](#stmt.return.coroutine-2.2.sentence-2)
[3](#stmt.return.coroutine-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1200)
If a search for the name return_void in the scope of the promise type
finds any declarations,
flowing off the end of a coroutine's [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") is equivalent to a co_return with no operand;
otherwise flowing off the end of a coroutine's [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") results in undefined behavior[.](#stmt.return.coroutine-3.sentence-1)
### [8.8.6](#stmt.goto) The goto statement [[stmt.goto]](stmt.goto)
[1](#stmt.goto-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1211)
The goto statement unconditionally transfers control to the
statement labeled by the identifier[.](#stmt.goto-1.sentence-1)
The identifier shall be a[label](stmt.label "8.2Label[stmt.label]") located in the current function[.](#stmt.goto-1.sentence-2)