Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
309 views
in Technique[技术] by (71.8m points)

c++ - Is it direct-initialization or copy-initialization?

Initializing objects (instances of classes or structs) in C++ can be done in various ways. Some syntaxes evoke a direct-initialization of your object, other syntaxes lead to a copy-initialization. With copy-elision enabled in the compiler, both have identical performance. With copy-elision disabled, there is an additional copy/move constructor call upon every instantiation when you choose for the latter (copy-initialization).

Conclusion: copy-initialization can have a performance-penalty!

From the following question: C++11 member initializer list vs in-class initializer? I can conclude that this would be copy-initialization syntax:

obj s = obj("value");

And this would be direct-initialization syntax:

obj s{"value"};

 
But what about this one:

obj s = {"value"};

And this one:

obj s = obj{"value"};

And this one:

obj s("value");

Or this one:

obj s = "value";

NOTE
Bjarne Stroustrup compares a few initialization styles (but not all) in his book "Programming, Principles and Practice Using C++" 2nd edition, on page 311, §9.4.2:

struct Date {
    int y,m,d;                     //year, month, day
    Date(int y, int m, int d);     //check for valid date and initialize
    void add_day(int n);           //increase the Date by n days
};

...

Date my_birthday;                   //error: my_birthday not initialized
Date today{12,24,2007};             //oops! run-time error
Date last{2000,12,31};              //OK (colloquial style)
Date next = {2014,2,14};            //also OK (slightly verbose)
Date christmas = Date{1976,12,24};  //also OK (verbose style)

Mr. Stroustrup presents these different initialization styles as equal. At least, that's how it looks to me. Nevertheless, it could still be possible that some are direct-initialization and others copy-initialization, since those terms are not yet discussed at that point in the book.


EDIT
The given answers bring up something interesting.
Apparently, this is direct-initialization:

obj s("value");

And this is direct-list-initialization:

obj s{"value"};

As some of you point out, there is a difference. In what way do they actually differ? Would the difference be noticeable in the output of a non-optimizing compiler?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In general:

In copy-initialization, the right-hand side is implicitly converted to a temporary instance of the type T, from which s is subsequently copy/move-constructed.

Mr. Stroustrup presents these different initialization styles as equal.

In many cases the generated (optimized) code is indeed exactly the same. Compilers are allowed to elide the copy construction (even if it has side effects). Modern compilers are well beyond simple optimizations such as this one so you can effectively count on this elision (which is required in C++17).

The difference between copy and direct initialization is nevertheless very important because the semantics are different; for example, invoking constructors declared explicit is only possible in direct-initialization.


1 The form T s = {...}; is copy-list-initialization and follows some special list-initialization rules.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...