<br><br><div class="gmail_quote">On Sat, Sep 17, 2011 at 7:56 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<font face="arial,helvetica,sans-serif">I was wondering if this is a bug in the gcc 4.5.2 standard library or a bug in clang... and I'd really appreciate a work-around if anyone has one, since I'm pretty much stuck at this point.</font></blockquote>



<div><br></div></div></div><div>As a baseline, this code compiles successfully when using libc++ (compile with -stdlib=libc++, though you'll of course need to install libc++) & I seem to have a repro of your errors with libstdc++ so I'm playing around with that now.</div>

</div></blockquote><div><br></div></div><div>I've investigated this a bit further with some help & I believe this is a bug in clang ToT surrounding implicit move constructor/assignment.</div></div></blockquote><div>
<br></div><div>On further further investigation (& getting to what I think is the code that's generating this - and, helpfully, quotes the standard that supports it) I believe this is by design & libstdc++ has a bug.</div>
<div><br></div><div>The relevant portion of the standard is 12.8[class.copy] paragraph 7:</div><div><br></div><div>    ... If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor</div>
<div>is defined as deleted; otherwise, it is defined as defaulted. ...</div><div><br></div><div>libstdc++'s std::pair should be defining the move/copy ctors/assignment operators (there's similar clauses for all these implicit definitions) explicitly if it wants to define the move assignment operator explicitly.</div>
<div><br></div><div>[Miles: sorry about that, I'm checking your bug/repro now, but I'd hazard it's the same thing & a bug in boost rather than clang. I'll update when I've looked at it some more]</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="gmail_quote"><div><br></div><div>Given this:</div>
<div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote"><div><div>struct foo {</div></div></div><div class="gmail_quote"><div><div>
  void operator=(foo&&);</div></div></div><div class="gmail_quote"><div><div>};</div></div></div><div class="gmail_quote"><div><div><br></div></div></div><div class="gmail_quote"><div><div>int main() {</div></div>

</div><div class="gmail_quote"><div><div>  foo g((foo()));</div></div></div><div class="gmail_quote"><div><div>}</div></div></div></blockquote><div class="gmail_quote"><div><br></div><div>Clang's output is:</div><div>

<span style="font-family:'Times New Roman';font-size:medium"><pre><span style="font-weight:bold">    simple.cc:6:7: </span><span></span><span style="color:red;font-weight:bold">error: </span><span></span><span style="font-weight:bold">call to deleted constructor of 'foo'
</span><span>      foo g((foo()));
</span><span style="color:green;font-weight:bold">          ^ ~~~~~~~
</span><span></span><span style="font-weight:bold">    simple.cc:1:8: </span><span></span><span style="color:gray;font-weight:bold">note: </span><span>function has been explicitly marked deleted here
</span><span>    struct foo {
</span><span style="color:green;font-weight:bold">           ^</span><br></pre></span></div></div>[g++ compiles this without error]<div><br></div><div>Clang seems to be implementing not providing implicit move operations by implementing them as deleted rather than as not present. This would be incorrect & produces the failure above.</div>

<div><br></div><div>The reason this came up in std::pair is a bit weird - it seems libstdc++'s std::pair has none of the big 5 (copy ctor, move ctor, copy assignment, move assignment, destructor) /except/ the move assignment operator. It does however have member function templates that, while not technically copy/move construction/assignment, are probably good enough for most cases. (returning a temporary probably should invoke the copy ctor of libstdc++'s pair, though, since it doesn't have a real move ctor which it should have)<br>

<br>Anyway, the presence of the move assignment operator caused clang to provide a deleted move ctor rather than no move ctor at all.</div><div><br></div><div>So there's the tale - I'll look into a fix & you'd be welcome to file a bug (& assign it to me, though if someone else on the list really wants to take it I don't mind), Matthieu. Thanks for bringing this up.</div>

<div><br></div><div>[side note: we should do a better job about the warning on "The Most Vexing Parse" (see the declaration of 'g' in the above example which required the extra () to be a variable declaration instead of a function declaration) - like the parantheses warning I think we should have a couple of notes suggesting the two ways to address the issue - most likely the user actually meant to declare a variable & should insert the extra (). But alternatively they can avoid the warning by removing the extra () after the 'foo' in the argument list.]</div>

<div><br></div><font color="#888888"><div>- David</div><div><br></div><div><br></div>
</font></blockquote></div><br>