what are rules about when the return type is reference

为君一笑 提交于 2020-04-16 03:29:05

问题


#include <iostream>
int func0(){
  int a = 0;
  return a;
}
int&& func1(){
   int a = 0;
   return a;
}
int main(){
  int&& result0 = func0();
  int&& result1 = func1();
}

return statement rules are:

  1. A function returns to its caller by the return statement.
  2. [...] the return statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function call by copy-initialization from the operand.

The rule about how to initialize the object of the function call is only #2.

We know the expression func0() is a prvalue. The reference result0 need to bind an object, so temporary materialization conversion shall covert the prvalue to an xvalue, So the temporary object as the prvalue result object is initialized from the operand of return, then the reference reusult0 bind to the temporary object.

But we know the result1 is a reference and the return type of func1 is also reference. For this case, [stmt.return] does not clearly cover this case, because result1 is a reference rather than object(neither glvalue reuslt object nor prvalue result object), so what the rules about this case? If I miss something, please correct me.


回答1:


Your analysis of result0 is correct.

But there's no temporary materialization in the result1 case. The "glvalue result" is a reference initialized by copy-initialization from the operand a, and copy-initialization of a reference to the same type means that the reference binds directly (dcl.init.ref/5, via dcl.init/17.2). Then result1 binds to the glvalue result.

This creates a dangling reference; a return statement is explicitly excluded from the lifetime extension rules (class.temporary/6.2).

In the case int result2 = func1(); then the glvalue result (a reference) undergoes lvalue-to-rvalue conversion with result object result2 , this causes undefined behaviour since the glvalue result was dangling.




回答2:


We know the expression func0 is a prvalue

Incorrect. func0 (the function name expression) is an lvalue. You are thinking of func0() (the function call expression) which is indeed a prvalue. The rest of the paragraph is correct.

I don't really follow your second paragraph so let me phrase it:

func1() is an xlvalue and the reference result will bind to that xvalue.

Very important: because you are returning a reference to an automatic storage variable you are left with a dangling reference.




回答3:


For this case, [stmt.return] does not clearly cover this case, because result1 is a reference rather than object(neither glvalue reuslt object nor prvalue result object), ...

No, it covers. Note the rule says "glvalue result or prvalue result object", which is not "glvalue result object or prvalue result object". See [basic.lvalue]/5:

The result of a glvalue is the entity denoted by the expression. The result of a prvalue is the value that the expression stores into its context; a prvalue that has type cv void has no result. A prvalue whose result is the value V is sometimes said to have or name the value V. The result object of a prvalue is the object initialized by the prvalue; ...

So the reference entity of the result of func1() is initialized with a.



来源:https://stackoverflow.com/questions/61004727/what-are-rules-about-when-the-return-type-is-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!