Title
Return type deduction from return with no operand
Status
cd4
Section
9.2.9.7 [dcl.spec.auto]
Submitter
Daveed Vandevoorde

Created on 2014-02-20.00:00:00 last changed 86 months ago

Messages

Date: 2014-11-15.00:00:00

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

Date: 2014-06-15.00:00:00

Proposed resolution (June, 2014):

Change 9.2.9.7 [dcl.spec.auto] paragraph 7 as follows:

When a variable declared using a placeholder type is initialized, or a return statement occurs in a function declared with a return type that contains a placeholder type, the deduced return type or variable type is determined from the type of its initializer. In the case of a return with no operand or with an operand of type void, the initializer declared return type shall be auto and the deduced return type is void considered to be void(). Let Otherwise, let T be the declared type...
Date: 2014-06-15.00:00:00

Notes from the June, 2014 meeting:

The last part of the issue is not a defect, because the unary * operator requires its operand to be a pointer to an object or function type, and void is neither, so the expression is ill-formed and deduction does not occur for that case.

It was also observed during the discussion that the same deduction problem occurs when returning an expression of type void as when the expression is omitted, so the resolution should cover both cases.

Date: 2014-02-20.00:00:00

Return type deduction from a return statement with no expression is described in 9.2.9.7 [dcl.spec.auto] paragraph 7 as follows:

When a variable declared using a placeholder type is initialized, or a return statement occurs in a function declared with a return type that contains a placeholder type, the deduced return type or variable type is determined from the type of its initializer. In the case of a return with no operand, the initializer is considered to be void(). Let T be the declared type of the variable or return type of the function. If the placeholder is the auto type-specifier, the deduced type is determined using the rules for template argument deduction. If the deduction is for a return statement and the initializer is a braced-init-list (9.4.5 [dcl.init.list]), the program is ill-formed. Otherwise, obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list, with std::initializer_list<U>. Deduce a value for U using the rules of template argument deduction from a function call (13.10.3.2 [temp.deduct.call]), where P is a function template parameter type and the initializer is the corresponding argument.

However, this does not work: the deduction for an argument of void() would give a parameter type of void and be ill-formed. It would be better simply to say that the deduced type in this case is void.

In a related example, consider

  decltype(auto) f(void *p) {
    return *p;
  }

This is presumably an error because decltype(*p) would be void&, which is ill-formed. Perhaps this case should be mentioned explicitly.

History
Date User Action Args
2017-02-06 00:00:00adminsetstatus: drwp -> cd4
2015-05-25 00:00:00adminsetstatus: dr -> drwp
2015-04-13 00:00:00adminsetmessages: + msg5363
2014-11-24 00:00:00adminsetstatus: ready -> dr
2014-07-07 00:00:00adminsetmessages: + msg5067
2014-07-07 00:00:00adminsetmessages: + msg5066
2014-07-07 00:00:00adminsetstatus: open -> ready
2014-02-20 00:00:00admincreate