Home > Article > Backend Development > Why Is the Move Constructor Not Called in C 11 When Copy Elision Is Enabled?
C 11 Move Constructor Not Called, Default Constructor Preferred
When working with classes in C , it's expected that move constructors will be utilized for efficient resource transfer. However, in some cases, the default constructor may be unexpectedly chosen instead.
Problem Statement
Consider the following class:
<code class="cpp">class X { public: explicit X(char* c) { cout << "ctor" << endl; init(c); } X(X& lv) { cout << "copy" << endl; init(lv.c_); } X(X&& rv) { cout << "move" << endl; c_ = rv.c_; rv.c_ = nullptr; } const char* c() { return c_; } private: void init(char* c) { c_ = new char[strlen(c) + 1]; strcpy(c_, c); } char* c_; };</code>
With the sample usage:
<code class="cpp">X x("test"); cout << x.c() << endl; X y(x); cout << y.c() << endl; X z(X("test")); cout << z.c() << endl;</code>
The expected output is:
ctor test copy test ctor move test
However, the last line unexpectedly outputs "ctor" instead of "move."
Explanation
According to the C 11 standard, move constructors should be called in certain situations. In this case, a move should occur when constructing z with X("test"). However, the default constructor is called instead.
This behavior is due to copy elision, an optimization technique that allows the compiler to directly construct a temporary into a target without performing a copy or move operation. This optimization applies in cases where the compiler determines that the copy/move operation is unnecessary and can be elided.
In the given scenario, the compiler considers the temporary X("test") a candidate for copy elision, as it is automatically created and destroyed within the same expression. Consequently, it omits the move operation and constructs z directly using the temporary's data, resulting in the call to the default constructor.
Conclusion
Copy elision can lead to unexpected behavior when working with move constructors, as it can prevent the move constructor from being invoked in situations where it is expected. Compilers may apply copy elision based on their optimization heuristics, which can vary between compilers and optimization settings. It's important to be aware of copy elision and its potential impact on program behavior.
The above is the detailed content of Why Is the Move Constructor Not Called in C 11 When Copy Elision Is Enabled?. For more information, please follow other related articles on the PHP Chinese website!