2

as far as I understand in C++ is an initialization in the form

T x = a;

called copy-initialization and an initialization in the form

T x(a);

or

T x{a};

called direct-initialization.

(T...Type, x...variable name, a...expression)

For class types I think the difference is clear (calling copy constructor in case of copy-initialization).

But what if primitive (scalar) types like int are used? Because an int type has no (copy-)constructor which constructor should be called in case of

int x = 5; // copy-initialization

So is there a difference?

int x = 5; // copy-initialization of variable x
int x = {5}; // copy-initialization of variable x
int x(5); // direct-initialization of variable x
int x{5}; // direct-initialization of variable x

What happens here exactly? Or is there no difference if primitive/scalar types are involved and all is syntactic sugar. Similar questions doesnt explain that exactly for me.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
knowledge
  • 941
  • 1
  • 11
  • 26
  • Then this applies _"...Otherwise (if neither T nor the type of other are class types), standard conversions are used, if necessary, to convert the value of other to the cv-unqualified version of T...."_ from: https://en.cppreference.com/w/cpp/language/copy_initialization – Richard Critten Sep 03 '19 at 12:25
  • 1
    FWIW `T foo = prvalue` no longer calls the copy constructor. Thanks to [guaranteed copy elision](https://stackoverflow.com/questions/38043319/how-does-guaranteed-copy-elision-work) it becomes `T foo(prvalue)` – NathanOliver Sep 03 '19 at 12:35
  • Note that there is one important fact about _list-initialization_ — it does not allow _narrowing conversions_. Therefore `int x = 5.0;` and `int x(5.0);` is both ok, but `int x{5.0};` and `int x = {5.0};` will fail. – Daniel Langr Sep 03 '19 at 12:40
  • Also note that the C++ Standard only defines behavior of code translated and run on an [**abstract machine**](http://eel.is/c++draft/intro.abstract). Implementation (a compiler) is free to translate each of your declarations into different assembly code. Nevertheless, any sane compiler very likely won't do this. – Daniel Langr Sep 03 '19 at 12:46

1 Answers1

1

There is no difference for primitive scalars like this; the memory location or register (depending on usage) is going to be initialized the same way.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Is there a quote from standard or something which say that there is no difference for primitives? – knowledge Sep 03 '19 at 12:26
  • 1
    @knowledge: Honestly, I didn't bother looking; every compiler on the planet will behave this way, because there is no other meaningful behavior to use that would provide any benefit (I suppose you *could* have the copy initialization approach always store the constant in some memory location in the binary, rather than just doing a store of an immediate, where direct initialization favors storing an immediate, but it's an insane policy choice to make, and not one the C++ standard has any interest in controlling). – ShadowRanger Sep 03 '19 at 12:32
  • 1
    @knowledge I believe you are looking for these paragraphs from the Standard: http://eel.is/c++draft/dcl.init#17.9 and http://eel.is/c++draft/dcl.init#list-3.9. – Daniel Langr Sep 03 '19 at 12:41