Sequencing of function parameter destruction : <p>According to C++14 [expr.call]/4:</p>

<blockquote>
  <p>The lifetime of a parameter ends when the function in which it is defined returns.</p>
</blockquote>

<p>This seems to imply that a parameter's destructor must run before the code which called the function goes on to use the function's return value. </p>

<p>However, this code shows differently:</p>

<pre><code>#include &lt;iostream&gt;

struct G
{
    G(int): moved(0) { std::cout &lt;&lt; "G(int)\n"; }
    G(G&amp;&amp;): moved(1) { std::cout &lt;&lt; "G(G&amp;&amp;)\n"; }
    ~G() { std::cout &lt;&lt; (moved ? "~G(G&amp;&amp;)\n" : "~G()\n"); }

    int moved;
};

struct F
{
    F(int) { std::cout &lt;&lt; "F(int)\n"; }
    ~F() { std::cout &lt;&lt; "~F()\n"; }
};

int func(G gparm)
{
    std::cout &lt;&lt; "---- In func.\n";
    return 0;
}


int main()
{
    F v { func(0) };
    std::cout &lt;&lt; "---- End of main.\n";
    return 0;
}
</code></pre>

<p>The output for gcc and clang , with <code>-fno-elide-constructors</code>, is (with my annotations):</p>

<pre><code>G(int)               // Temporary used to copy-initialize gparm
G(G&amp;&amp;)               // gparm
---- In func.
F(int)               // v
~G(G&amp;&amp;)              // gparm
~G()                 // Temporary used to copy-initialize gparm
---- End of main.
~F()                 // v
</code></pre>

<p>So, clearly <code>v</code>'s constructor runs before <code>gparm</code>'s destructor.  But in MSVC, <code>gparm</code> is destroyed before <code>v</code>'s constructor runs.</p>

<p>The same issue can be seen with copy-elision enabled, and/or with <code>func({0})</code> so that the parameter is direct-initialized. <code>v</code> is always constructed before <code>gparm</code> is destructed. I also observed the issue in a longer chain, e.g. <code>F v = f(g(h(i(j())));</code> did not destroy any of the parameters of <code>f,g,h,i</code> until after <code>v</code> was initialized.</p>

<p>This could be a problem in practice, for example if <code>~G</code> unlocks a resource and <code>F()</code> acquires the resource, it would be a deadlock. Or, if <code>~G</code> throws, then execution should jump to a catch handler without <code>v</code> having been initialized.</p>

<p>My question is: does the standard permit both of these orderings? . Is there any more specific definition of the sequencing relationship involving parameter destruction, than just that quote from expr.call/4 which does not use the standard sequencing terms?</p>
