2

Copy initialization is when Hello is created in memory and then being used copy constructor to initialize s, right?

std::string s = std::string("Hello")

After C++11 where move semantics is introduced can I say that the code above is as effective (eliminates copy) as in this case:

std::string s("Hello");

EDIT: please don't answer for string. string was just and example of a class. SSO is not the case what I ask. I ask in general.

Narek
  • 35,407
  • 69
  • 202
  • 359
  • When you use strings smaller than 20 characters (depending on the implementation), short string optimization kicks in, and everything is copied anyway. – imreal Aug 24 '15 at 14:46
  • @imreal That doesn't need to be *exactly* 20 characters. Moreover, details *and* presence of short string optimization are totally implementation dependent. – Mateusz Grzejek Aug 24 '15 at 14:50
  • @MateuszGrzejek,yes, that's why I wrote "(depending on the implementation)" – imreal Aug 24 '15 at 14:51
  • If you don't want to know about string, change the name of the class in your example to a user created class. – Rob K Aug 24 '15 at 15:04
  • @RobK it is late already. :) I just commented hoping that the answers will also cover the general case too. – Narek Aug 24 '15 at 15:20

3 Answers3

1

When you use strings smaller than 20 characters (depending on the implementation), short string optimization kicks in, and everything is copied anyway.

But to answer your question, move semantics is not used in any of your examples anyway. In the first case even if both copy constructor and string(const char*) constructors must be available, copy elision will eliminate the copy.

EDIT:

To address your edit, if you have one initialization and one initialization + move constructor, the former will obviously always be faster. The reason I brought up SSO is because people assumes that move operations are always cheap (or even free), but not necessarily and sometimes they don't even happen at all.

imreal
  • 9,700
  • 2
  • 28
  • 45
  • You mean if those are not `std::string`s then still `A a("Hello");` is preferred, right? – Narek Aug 24 '15 at 15:31
  • 1
    @Narek, yes in cases where move will happen, although in that particular case, copy elision will almost certainly happen. – imreal Aug 24 '15 at 15:33
1

Short answer: performances should be the same if copy elision is performed. Otherwise the latter should probably be faster.


Long answer:

This code

std::string s = std::string("Hello")

should call a move constructor in C++11+ code (it requires an accessible one). Anyway copy elision is allowed in this case, although not mandated (cfr. [class.copy]/p31)

When certain criteria are met, an implementation is allowed to omit the copy/move construction

These are concepts that were already present in pre-C++11 though (they applied to copy constructors as well).

As to the performances question:

The standard also describes a few situations where copying can be eliminated even if this would alter the program's behavior, the most common being the return value optimization. Another widely implemented optimization, described in the C++ standard, is when a temporary object of class type is copied to an object of the same type.[1] As a result, copy-initialization is usually equivalent to direct-initialization in terms of performance, but not in semantics; copy-initialization still requires an accessible copy constructor.[2]

Source - Copy elision

If copy elision doesn't take place (e.g. it has been disabled in gcc via -fno-elide-constructors or for whatever reason the compiler won't perform it) then performances will probably not be the same and direct initialization should be faster (in this case for std::string SSO might also take a toll on the move)

Community
  • 1
  • 1
Marco A.
  • 41,192
  • 25
  • 117
  • 233
0

Actually, this was the case before C++11 because of copy elision.

Note that std::string is not necessarily cheap to move, as small strings may be held in the object itself rather than being dynamically allocated. This is known as small string optimisation.

Community
  • 1
  • 1
TartanLlama
  • 59,364
  • 11
  • 141
  • 183