Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does this code causes UB? [duplicate]

Tags:

c++

I have checkd gcc and clang and both does not generate any warnings. I suppose that lifetime of temporary from foo() will be prolonged untill the end of full expression which is where semicolon in bar function call is located.

#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
}
like image 401
mike Avatar asked Sep 27 '16 08:09

mike


2 Answers

The temporary 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
}

Classical undefined behaviour case :

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

Temporary std::string is created, a pointer to it's buffer is returned by c_str() and the temporary goes out of scope and is destroyed. charPtr now is a pointer pointing to an invalid location ( a dead std::string ).

like image 124
Hatted Rooster Avatar answered Oct 21 '22 05:10

Hatted Rooster


bar(a.foo().c_str());
bar(a.foo().substr().c_str());

Short answer - Yes, both are safe.

What you're looking at is an rvalue.

An rvalue (so-called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object or subobject thereof, or a value that is not associated with an object.

Read more: What are rvalues, lvalues, xvalues, glvalues, and prvalues?

like image 34
Ivan Rubinson Avatar answered Oct 21 '22 05:10

Ivan Rubinson