[stmt.return]

# 8 Statements [[stmt]](./#stmt)

## 8.8 Jump statements [[stmt.jump]](stmt.jump#stmt.return)

### 8.8.4 The return statement [stmt.return]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L1063)

A function returns control to its caller by the return statement[.](#1.sentence-1)

[2](#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[.](#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"))[.](#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[.](#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[.](#2.sentence-4)

[*Note [1](#note-1)*:

A constructor or destructor does not have a return type[.](#2.sentence-5)

â *end note*]

[*Note [2](#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[.](#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"))[.](#2.sentence-7)

â *end note*]

[3](#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"))[.](#3.sentence-1)

[*Example [1](#example-1)*: class A {~A() {}};
A f() { return A(); } // error: destructor of A is private (even though it is never invoked) â *end example*]

[4](#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[.](#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[.](#4.sentence-2)

[5](#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]](stmt.jump "8.8 Jump statements")) of the block
enclosing the return statement[.](#5.sentence-1)

[*Note [3](#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"))[.](#5.sentence-2)

â *end note*]

[6](#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[.](#6.sentence-1)

[*Example [2](#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*]
