This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


1885. Return value of a function is underspecified

Section: 7.6.1.3  [expr.call]     Status: CD4     Submitter: Jens Maurer     Date: 2014-02-28

[Moved to DR at the November, 2014 meeting.]

The intent is that a function call is a temporary expression whose result is a temporary, but that appears not to be said anywhere. It should also be clarified that a return statement in a function with a class return type copy-initializes the temporary that is the result. The sequencing of the initialization of the returned temporary, destruction of temporaries in the return expression, and destruction of automatic variables should be make explicit.

Proposed resolution (October, 2014):

Change 8.7.4 [stmt.return] paragraphs 2-3 as follows:

A return statement with neither an expression nor a braced-init-list can be used only in functions that do not return a value, that is, The expression or braced-init-list of a return statement is called its operand. A return statement with no operand shall be used only in a function with the whose return type is cv void, a constructor (11.4.5 [class.ctor]), or a destructor (11.4.7 [class.dtor]). A return statement with an operand of type void shall be used only in a function whose return type is cv void. A return statement with an expression of non-void type can be used only any other operand shall be used only in functions returning a value; the value of the expression is returned to the caller of the function. The value of the expression is implicitly converted to the return type of the function in which it appears a function whose return type is not cv void; the return statement initializes the object or reference to be returned by copy-initialization (9.4 [dcl.init]) from the operand. [Note: A return statement can involve the construction and copy or move of a temporary object (6.7.7 [class.temporary]). [Note: A copy or move operation associated with a return statement may be elided or considered as an rvalue for the purpose of overload resolution in selecting a constructor (11.4.5.3 [class.copy.ctor]). —end note] A return statement with a braced-init-list initializes the object or reference to be returned from the function by copy-list-initialization (9.4.5 [dcl.init.list]) from the specified initializer list. [Example:

  std::pair<std::string,int> f(const char* p, int x) {
    return {p,x};
  }

end example] Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

A return statement with an expression of type void can be used only in functions with a return type of cv void; the expression is evaluated just before the function returns to its caller. The copy-initialization of the returned entity 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 (8.7 [stmt.jump]) of the block enclosing the return statement.

(See also the related changes in the resolution of issue 1299.)