Does this code call UB?

I have checkd gcc and clang and both of them do not generate any warnings. I believe that the lifetime of the temporary one from foo () will be extended to the end of the full expression, where is the semicolon in the bar function call.

#include <iostream> #include <string> struct A { std::string foo() const{ return "aaa"; } }; void bar(const char* c) { std::cout << c; } int main() { A a; bar(a.foo().c_str()); // Is this safe? bar(a.foo().substr().c_str()); // or this } 
+5
source share
2 answers

The temporary expression returned by foo() (and substr() ) will continue to exist until the end of the bar call (after the chain of method calls), this is safe.

 int main() { A a; bar(a.foo().c_str()); //temporary is destroyed here bar(a.foo().substr().c_str()); // and here } 

The classic case of undefined behavior:

 int main() { A a; const char* charPtr = a.foo().c_str(); printf("%s", charPtr); } 

A temporary std::string , a pointer to its buffer is returned by c_str() , and the temporary one goes out of scope and is destroyed. charPtr now a pointer pointing to an invalid location (dead std::string ).

+7
source
 bar(a.foo().c_str()); bar(a.foo().substr().c_str()); 

The short answer is Yes, both are safe.

What you are looking at is an rvalue.

The value of r (the so-called, historically, because rvalues ​​can appear on the right side of the assignment expression) is an xvalue, a temporary object or subobject, or a value that is not associated with the object.

More: What are rvalues, lvalues, xvalues, glvalues, and prvalues?

+2
source

All Articles