Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if I return literal instead of declared std::string?

Tags:

c++

c++11

Say we have an utility function:

std::string GetDescription() { return "The description."; }

Is it OK to return the string literal? Is the implicitly created std::string object copied?

I thought about always returning it like this:

std::string GetDescription() { return std::move(std::string("The description.")); }

But it's of course longer and more verbose. We could also assume that compiler RVO will help us a bit

std::string GetDescription() { return std::string("The description."); }

Yet still, I don't know what it really has to do, instead of what can it do.

like image 578
Bartek Banachewicz Avatar asked Dec 13 '12 10:12

Bartek Banachewicz


People also ask

Is std::string a literal type?

std::string literals are Standard Library implementations of user-defined literals (see below) that are represented as "xyz"s (with a s suffix).

Is string a literal type C++?

In C++, an ordinary string literal has type 'array of n const char'. For example, The type of the string literal "Hello" is "array of 6 const char". It can, however, be converted to a const char* by array-to-pointer conversion.

Is std::string allocated on the heap?

The string object itself is stored on the stack but it points to memory that is on the heap. Why? The language is defined such that the string object is stored on the stack. string's implementation to construct an object uses memory on the heap.

What is a string literal C++?

A string literal contains a sequence of characters or escape sequences enclosed in double quotation mark symbols. A string literal with the prefix L is a wide string literal. A string literal without the prefix L is an ordinary or narrow string literal.


2 Answers

std::string GetDescription() { return "XYZ"; }

is equivalent to this:

std::string GetDescription() { return std::string("XYZ"); }

which in turn is equivalent to this:

std::string GetDescription() { return std::move(std::string("XYZ")); }

Means when you return std::string("XYZ") which is a temporary object, then std::move is unnecessary, because the object will be moved anyway (implicitly).

Likewise, when you return "XYZ", then the explicit construction std::string("XYZ") is unnecessary, because the construction will happen anyway (implicitly).


So the answer to this question:

Is the implicitly created std::string object copied?

is NO. The implicitly created object is after all a temporary object which is moved (implicitly). But then the move can be elided by the compiler!

So the bottomline is this : you can write this code and be happy:

std::string GetDescription() { return "XYZ"; }

And in some corner-cases, return tempObj is more efficient (and thus better) than return std::move(tempObj).

like image 86
Nawaz Avatar answered Oct 24 '22 18:10

Nawaz


Is it OK to return the string literal? Is the implicitly created std::string object copied?

It is OK. What you get, is the (implicit) constructor for std::string, creating a local copy, returned then as a rvalue reference. Taking the result in client code into a string, will set that string from an rvalue reference.

If you use the second piece of code, you "say too much". The code is correct, and they are (almost) equivalent (they should be equivalent, but the optimizations that the compiler is permitted to perform in the first case are better*).

I would go for:

std::string GetDescription() { return std::string("The description."); }

This way it is explicit that you return a string, and the code is (almost) minimal: you rely on the std::string move-construction.

*) edited accordingly, after comment by @SteveJessop.

like image 1
utnapistim Avatar answered Oct 24 '22 18:10

utnapistim