From cppreference.com
Terminates the current function and returns the specified value (if any) to the caller.
Syntax
attr(optional)returnexpression(optional);(1) attr(optional)returnbraced-init-list;(2) (since C++11)attr(optional)co_returnexpression(optional);(3) (since C++20)attr(optional)co_returnbraced-init-list;(4) (since C++20)Explanation
1) Evaluates the expression, terminates the current function and returns the result of the expression to the caller, after
to the function return type. The expression is optional in functions whose return type is (possibly cv-qualified) void, and disallowed in constructors and in destructors.
3,4) In a coroutine, the keyword co_return must be used instead of return for the final suspension point (see
for details).
The expressionor braced-init-list(since C++11) (if any) is known as the operand of the return statement.
There is a
between the copy-initialization of the result of the function call and the destruction of all temporaries at the end of expression.
(until C++11)The copy-initialization of the result of the function call is
the destruction of all temporaries at the end of expression, which, in turn, is sequenced-before the destruction of local variables of the block enclosing the return statement.
(since C++11)If the return type of the function is a reference type and a return statement (1,2) binds the returned reference to the result of a
, the program is ill-formed.
(since C++26)If control reaches the end of
a function with the return type (possibly cv-qualified) void,
a constructor,
a destructor, or
a
for a function with the return type (possibly cv-qualified) void
without encountering a return statement, return; is executed.
If control reaches the end of the
, return0; is executed.
Flowing off the end of a value-returning function, except the main function and specific
(since C++20), without a return statement is undefined behavior.
In a function returning (possibly cv-qualified) void, the return statement with expression can be used, if the expression type is (possibly cv-qualified) void.
If the return type of a function is specified as a
, it will be
from the return value. If decltype(auto) is used, the type deduction treats an expression that can be an entity as an entity.
(since C++14)Notes
Returning by value may involve construction and copy/move of a temporary object, unless
is used. Specifically, the conditions for copy/move are as follows:
Automatic move from local variables and parameters
The expression is move-eligible if it is a (possibly parenthesized)
that names a variable of automatic storage duration whose type is
a non-volatile object type
(since C++11)or a non-volatile rvalue reference to object type
(since C++20)and that variable is declared
in the body
or as a parameter
of the innermost enclosing function or lambda expression.
(since C++11)If the expression is move-eligible,
to select the constructor to use for initialization of the returned value or, for co_return, to select the overload of promise.return_value()(since C++20) is performed twice :
first as if expression were an rvalue expression (thus it may select the
), and
if the first overload resolution failed
(since C++11)
(until C++23)or it succeeded, but did not select the
(formally, the first parameter of the selected constructor was not an rvalue reference to the (possibly cv-qualified) type of expression)
(since C++11)
(until C++20)then overload resolution is performed as usual, with expression considered as an lvalue (so it may select the
).
(since C++11)
(until C++23)If the expression is move-eligible, it is treated as an xvalue (thus overload resolution may select the
).
(since C++23)Guaranteed copy elision
If expression is a prvalue, the result object is initialized directly by that expression. This does not involve a copy or move constructor when the types match (see
).
(since C++17)Feature-test macroValueStdFeature
(C++23)Simpler
Keywords
,
Example
Run this code
#include<iostream>#include<string>#include<utility>voidfa(inti){if(i==2)return;std::cout<<"fa("<<i<<")\n";}// implied return;intfb(inti){if(i>4)return4;std::cout<<"fb("<<i<<")\n";return2;}std::pair<std::string,int>fc(constchar*p,intx){return{p,x};}voidfd(){returnfa(10);// fa(10) is a void expression}intmain(){fa(1);// prints its argument, then returnsfa(2);// does nothing when i == 2, just returnsinti=fb(5);// returns 4i=fb(i);// prints its argument, returns 2std::cout<<"i = "<<i<<'\n'<<"fc(~).second = "<<fc("Hello",7).second<<'\n';fd();}structMoveOnly{MoveOnly()=default;MoveOnly(MoveOnly&&)=default;};MoveOnlymove_11(MoveOnlyarg){returnarg;// OK. implicit move}MoveOnlymove_11(MoveOnly&&arg){returnarg;// OK since C++20. implicit move}MoveOnly&&move_23(MoveOnly&&arg){returnarg;// OK since C++23. implicit move}Output:
fa(1) fb(4) i = 2 fc(~).second = 7 fa(10) Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
C++98 expression could not be omitted if the return type is cv-qualified voidit can be omitted
C++11 return by converting move constructor was not allowed converting move
constructor lookup enabled
C++98 sequencing of the destruction of automatic variables was not explicit sequencing rules added See also