Temporary and expression behavior

2019-07-20 14:25发布

问题:

Is this well defined behavior?

const char* p = (std::string("Hello") + std::string("World")).c_str();
std::cout << p;

I am not sure. Reasons?

回答1:

No, this is undefined behavior. Both std::string temporaries and the temporary returned by operator+ only live until the end of the initialization of your const char* (end of full expression). Then they are destroyed and p points to uncertain memory.



回答2:

No the behaviour is undefined because p points to deallocated storage in std::cout << p;

A temporary is created to hold std::string("Hello") + std::string("World"). C-style string is then retrived from that object. At the end of the expression that temporary is destroyed leaving p pointing to a deallocated storage.

Using p then invokes Undefined Behavior.

12.2/4 says

There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when an expression appears as an initializer for a declarator defining an object. In that context, the temporary that holds the result of the expression shall persist until the object’s initialization is complete.
....



回答3:

it won't compile because of a missing semi-colon:

const char* p = (std::string("Hello") + std::string("World")).c_str(); //<< important here
std::cout << p;

NOW the rule applies that the temporary is deleted at the end of the expression it is used in, which is at the semicolon. So you have a pointer to deleted memory which causes undefined behaviour.



回答4:

I recently read this excellent book http://www.amazon.co.uk/Gotchas-Avoiding-Addison-Wesley-Professional-Computing/dp/0321125185/ref and if I recall correctly this is pretty much one of the examples given there.

I believe the data returned from c_str is only valid as long as the string object that returned it is live. The string objects in your example are only live for the duration of the expression.