Note that there are some explanatory texts on larger screens.

plurals
  1. POWhen will a C++11 compiler make RVO and NRVO outperform move semantics and const reference binding?
    text
    copied!<p>Consider the case when "whole" objects with move semantics enabled are returned from functions, as with <code>std::basic_string&lt;&gt;</code>:</p> <pre><code>std::wstring build_report() const { std::wstring report; ... return report; } </code></pre> <p>Can I then realistically be expected to make the "best" choice whether to use the returned string with move semantics, as in</p> <pre><code>const std::wstring report(std::move(build_report())); </code></pre> <p>or if I should rely on (N)RVO to take place with</p> <pre><code>const std::wstring report(build_report()); </code></pre> <p>or even bind a const reference to the temporary with</p> <pre><code>const std::wstring&amp; report(build_report()); </code></pre> <p><strong>What scheme is there to make a deterministic choice of these options, if any?</strong></p> <p><strong>EDIT 1:</strong> Note that the usage of <code>std::wstring</code> above is just an example of a move semantics enabled type. It just as well be swapped for your <code>arbitrary_large_structure</code>. :-)</p> <p><strong>EDIT 2:</strong> I checked the generated assembly when running a speed-optmized release build in VS 2010 of the following:</p> <pre><code>std::wstring build_report(const std::wstring&amp; title, const std::wstring&amp; content) { std::wstring report; report.append(title); report.append(content); return report; } const std::wstring title1(L"title1"); const std::wstring content1(L"content1"); const std::wstring title2(L"title2"); const std::wstring content2(L"content2"); const std::wstring title3(L"title3"); const std::wstring content3(L"content3"); int _tmain(int argc, _TCHAR* argv[]) { const std::wstring report1(std::move(build_report(title1, content1))); const std::wstring report2(build_report(title2, content2)); const std::wstring&amp; report3(build_report(title3, content3)); ... return 0; } </code></pre> <p>The 2 most interesting outcomes:</p> <ul> <li>Explicitly calling <code>std::move</code> for <code>report1</code> to use the move constructor <strong>triples</strong> the instruction count.</li> <li>As noted by James McNellis in <a href="https://stackoverflow.com/questions/6531700/when-will-a-c0x-compiler-make-rvo-and-nrvo-outperform-move-semantics-and-const/6531758#6531758">his answer below</a>, <code>report2</code> and <code>report3</code> does indeed generate identical assembly with 3 times fewer instructions than explicitly calling <code>std::move</code>.</li> </ul>
 

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