Note that there are some explanatory texts on larger screens.

plurals
  1. POMove constructor seemingly not executed
    text
    copied!<p>This is my first experiment with C++0x rvalue references and something strange seems to be going on.</p> <p>In the code sample below the factory function <code>MakeWindow</code> returns a Window object by value. The caller uses it to initialize a Window object. If I understood correctly, this should invoke the move constructor. In order to detect this I throw an exception there. On top of that I disabled the copy constructor:</p> <pre><code>#include &lt;iostream&gt; // Fake WinAPI typedef void* HWND; HWND CreateWindow() { return (void*)1; } void DestroyWindow(HWND) { } // End WinAPI // C++ WinAPI Wrapper Library class Window { public: Window(HWND inHandle) : mHandle(inHandle) { std::cout &lt;&lt; "Window constructor. Handle: " &lt;&lt; inHandle &lt;&lt; std::endl; } Window(Window &amp;&amp; rhs) : mHandle(rhs.mHandle) { std::cout &lt;&lt; "Window move constructor. Handle: " &lt;&lt; mHandle &lt;&lt; std::endl; rhs.mHandle = 0; throw 1; // this is my "breakpoint" } ~Window() { std::cout &lt;&lt; "Window destructor. Handle: " &lt;&lt; mHandle &lt;&lt; std::endl; if (mHandle) { DestroyWindow(mHandle); } } private: Window(const Window&amp;); Window&amp; operator=(const Window&amp;); HWND mHandle; }; // Factory function Window MakeWindow() { return Window(CreateWindow()); } int main() { { Window window(MakeWindow()); } std::cout &lt;&lt; "Everything is OK." &lt;&lt; std::endl; return 0; } </code></pre> <p>However the code runs fine without this exception being thrown. This is the console output:</p> <pre><code>Window constructor. Handle: 0x1 Window destructor. Handle: 0x1 Everything is OK. </code></pre> <p>If I comment out the move constructor then compilation fails with the following errors:</p> <pre><code>MysteryMove.cpp: In function 'Window MakeWindow()': MysteryMove.cpp:39:5: error: 'Window::Window(const Window&amp;)' is private MysteryMove.cpp:49:33: error: within this context MysteryMove.cpp: In function 'int main()': MysteryMove.cpp:39:5: error: 'Window::Window(const Window&amp;)' is private MysteryMove.cpp:57:35: error: within this context make: *** [all] Error 1 </code></pre> <p>It doesn't seem to make sense. Can anyone explain what is going on?</p> <h3>Update</h3> <p>Thanks to @Philipp I learned that move constructors can also be omitted. This is described in §12.8/34 and footnote 124 of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3126.pdf" rel="noreferrer">N3126 draft standard</a>.</p> <p>It is there also mentioned that RVO is only allowed for non-volatile objects. This means I can get around it writing the factory function like this:</p> <pre><code>// Factory function Window MakeWindow() { volatile Window window(CreateWindow()); return const_cast&lt;Window&amp;&amp;&gt;(window); } </code></pre> <p>And indeed it works:</p> <pre><code>Window constructor. Handle: 0x1 Window move constructor. Handle: 0x1 terminate called after throwing an instance of 'int' Abort trap </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload