Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
340 views
in Technique[技术] by (71.8m points)

c++ - Side effects of passing temporary as const T& and binding to class reference

Let's say I've a struct definition and some function like this:

struct A{
 const std::string& _s;
 A(const std::string& s):_s(s){}
 //A(const std::string s): _s(s){}
};
 int main(void){
    A a("E");
    std::cout << a._s << '
';
}

This doesn't error or warn at all by default, you can get it to throw an error at runtime by compiling with asan. From my understanding what happens is, the temporary "E to which s is bound to dies at the end of first expression, meaning A a("E") and therefore the reference in the class gets invalidated after that. So at the cout << point we are accessing a dangling reference.

At compile time, if we replace the first constructor with the 2nd, a warning is generated, that it's binding the reference to the temporary s and so now accessing s after the A a("E") expression is over is also UB.

Assuming the two cases are correct, is there ever a case where

auto x= A("E")._s

would be UB? And if so, when?

question from:https://stackoverflow.com/questions/65642004/side-effects-of-passing-temporary-as-const-t-and-binding-to-class-reference

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The c++17 standard §15.2 point 6.9 says

  • temporary object bound to a reference parameter in a function call (8.5.1.2) persists until the completion of the full-expression containing the call

So you are good. No UB here auto x= A("E")._s.

The other issues you have described well yourself. After construction accessing the member will be UB.

You can, however, extend the lifetime of a temporary object by binding it to a local const-reference like so:

struct A {
   const std::string& _s;
   A(const std::string& s) : _s(s) {}    
};

int main(void) {
   const std::string& e = "E";
   A a(e);
   std::cout << a._s << '
';
}

which would not be UB, but I would not use it like this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...