[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.1 General [stmt.jump.general]") break ; continue ; return [*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1 General [dcl.init.general]")opt ; [*coroutine-return-statement*](#nt:coroutine-return-statement "8.8.5 The co_­return statement [stmt.return.coroutine]") goto [*identifier*](lex.name#nt:identifier "5.11 Identifiers [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.4 Automatic 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.10 Declaration statement"))[.](#general-2.sentence-1) For temporaries, see [[class.temporary]](class.temporary "6.8.7 Temporary objects")[.](#general-2.sentence-2) However, the program can be terminated (by callingstd​::​exit() orstd​::​abort() ([[support.start.term]](support.start.term "17.5 Startup 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.4 Await")) 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.1 Preamble"))an [*iteration-statement*](stmt.iter.general#nt:iteration-statement "8.6.1 General [stmt.iter.general]") ([[stmt.iter]](stmt.iter "8.6 Iteration statements")), an [*expansion-statement*](stmt.expand#nt:expansion-statement "8.7 Expansion statements [stmt.expand]") ([[stmt.expand]](stmt.expand "8.7 Expansion statements")), or a switch statement ([[stmt.switch]](stmt.switch "8.5.3 The 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.1 Preamble"))an [*iteration-statement*](stmt.iter.general#nt:iteration-statement "8.6.1 General [stmt.iter.general]") or an [*expansion-statement*](stmt.expand#nt:expansion-statement "8.7 Expansion 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.1 General [stmt.iter.general]") ([[stmt.iter]](stmt.iter "8.6 Iteration statements")), the continue statement causes control to pass to the end of the [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]") or [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound 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.4 Compound statement or block [stmt.block]") of the current Si ([[stmt.expand]](stmt.expand "8.7 Expansion 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.1 General [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.5 Constructors")), or a destructor ([[class.dtor]](class.dtor "11.4.7 Destructors"))[.](#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.5 Initializers [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.6 Copy/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.7 Destructors"), [[except.ctor]](except.ctor "14.3 Stack 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.1 main function")) nor a coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine 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.10 Declaration statement")), which, in turn, is sequenced before the evaluation of postcondition assertions of the function ([[dcl.contract.func]](dcl.contract.func "9.4.1 General")), which, in turn, is sequenced before the destruction of function parameters ([[expr.call]](expr.call "7.6.1.3 Function 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.8 Relationships between types")), a return statement that binds the returned reference to a temporary expression ([[class.temporary]](class.temporary "6.8.7 Temporary 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(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.5 The co_­return statement [stmt.return.coroutine]") co_return [*expr-or-braced-init-list*](dcl.init.general#nt:expr-or-braced-init-list "9.5.1 General [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.4 Coroutine definitions"))[.](#stmt.return.coroutine-1.sentence-1) A coroutine shall not enclose a return statement ([[stmt.return]](#stmt.return "8.8.4 The 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.2 The 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.1 General [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.4 Coroutine 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.4 Coroutine 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.1 General [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.1 General [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.4 Compound statement or block [stmt.block]") { [*expression*](expr.comma#nt:expression "7.6.20 Comma 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.1 General [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.1 General [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.2 Label [stmt.label]") located in the current function[.](#stmt.goto-1.sentence-2)