<div class="gmail_quote">On Sat, Apr 14, 2012 at 12:13 AM, Jeff Walden <span dir="ltr"><<a href="mailto:jwalden%2Bclang@mit.edu">jwalden+clang@mit.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Just yesterday a few of us SpiderMonkey hackers stumbled upon the apparent C++98 oddity that binding a T temporary to a const U& (where U has a U(const T&) constructor) requires that T's copy constructor be accessible.  Here's a demonstration:<br>

<br>
> [jwalden@wheres-wally minimal]$ cat test.cpp<br>
> class A<br>
> {<br>
>   public:<br>
>     A() {}<br>
><br>
>   private:<br>
>     A(const A& a)<br>
> #ifdef DELETE_COPY_CTOR<br>
>       = delete<br>
> #endif<br>
>       ;<br>
> };<br>
><br>
> class B<br>
> {<br>
>   public:<br>
>     B(const A& a) {}<br>
> };<br>
><br>
> int main()<br>
> {<br>
>   B b = A();<br>
> }<br>
<br>
If you compile this without the =delete, you get warned that the copy constructor is inaccessible, and things still build.<br>
<br>
> [jwalden@wheres-wally minimal]$ ~/Programs/clang-build/build/Release/bin/clang++ -Wno-c++11-extensions test.cpp<br>
> test.cpp:22:9: warning: C++98 requires an accessible copy constructor for class 'A' when binding a reference to a temporary; was private<br>
>       [-Wbind-to-temporary-copy]<br>
>   B b = A();<br>
>         ^<br>
> test.cpp:7:5: note: declared private here<br>
>     A(const A& a)<br>
>     ^<br>
> 1 warning generated.<br></blockquote><div><br></div><div>This is a workaround for the fact that a terrifying amount of C++98 code was written against GCC, where such code (often) compiles without warning. The problem is that C++98 requires this copy constructor to exist, but does not require it to in fact be called. GCC only checks the copy constructor when it is going to be called, but Clang implements this rule precisely as written.</div>
<div><br></div><div>To cope with all of the code that in fact relies this, we made it a warning in Clang that can be disabled.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
On the other hand, if you compile this with =delete (as SpiderMonkey's code was doing), you get an error that a deleted constructor was invoked.  But you *don't* get a warning telling you that C++98 requires the copy constructor to be accessible.<br>
</blockquote><div><br></div><div>This just happens because of mixing C++11 and C++98 afaict.</div><div><br></div><div>C++11 provides the delete operator to more explicitly and clearly mark something as non-copyable, but it also provides new wording for cases like this to not require a copy constructor. When you use the delete operator as an extension, but continuing to build in C++98 results in the copy constructor being required in strange places.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
We devised a hackaround specific to the situation where we were hitting this problem, but we didn't understand why it was happening.  Only later, when reducing it to report a bug or determine that it wasn't a bug, did we discover the C++98 oddity.  It would have been much more readily apparent what the problem was if we'd had both diagnostics.<br>

<br>
I've attached a patch which, for this testcase at least, causes both errors to be emitted.</blockquote><div><br></div><div>I don't think this is much of an improvement really. At a fundamental level, we should either extend the exception to the rule to include deleted copy constructors, or not. If not, the current behavior seems correct.</div>
<div><br></div><div>While I sympathize with the desire to pick up delete and other C++11 features, I'm hesitant to extend logic in Clang far in the pursuit of using 'deleted' as a C++98 extension -- I'd rather focus on moving people to C++11 whole-sale.</div>
<div><br></div><div>Would it be possible to guard the use of the 'deleted' keyword on C++11 as a whole rather than on the extension alone?</div></div>