This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] rvalue reference implementation for C++0x

On Mon, 2007-04-30 at 18:51 -0400, Doug Gregor wrote:
> Looking more closely at this, I think Jason is right... the B(A)
> allows us to build a B, but we still need a copy constructor to make a
> copy of the B before binding the reference.

You don't need to make a copy of temporary value before binding a
reference to it. You used to need to check for a copy constructor, but
you don't anymore. In C++0x, compilers are required to do a direct
binding here. That's the point I was making at . And there's
more information about this in DR391: . 

>  Now, the compiler is
> permitted to elide the actual copy construction... but the copy
> constructor needs to be there even if the copy construction will be
> elided. I had thought that the rvalue references proposal change this,
> but it did not. This paragraph from N2118 points out explicitly that
> out explicitly:
> -16- When the criteria for elision of a copy operation are met and the
> object to be copied is designated by an lvalue, overload resolution to
> select the constructor for the copy is first performed as if the
> object were designated by an rvalue. If overload resolution fails, or
> if the type of the first parameter of the selected constructor is not
> an rvalue-reference to the object's type (possibly cv-qualified),
> overload resolution is performed again, considering the object as an
> lvalue. [Note: This two-stage overload resolution must be performed
> regardless of whether copy elision will occur. It determines the
> constructor to be called if elision is not performed, and the selected
> constructor must be accessible even if the call is elided. —end note]

This doesn't have anything to do with what is going on. None of the
changes in my patch cause the compiler to elide copies that it wouldn't
have elided previously. None of the changes in my patch cause the
compiler to skip checks for copy constructors when it elides copies.

The change in my patch that allows these testcases to compile is this
one in call.c:

-  if (lvalue_p && compatible_p)
+  /* Directly bind reference when target expression's type is compatible with
+     the reference and expression is an lvalue. In C++0x, the wording in
+     [8.5.3/5 dcl.init.ref] is changed to also allow direct bindings for const
+     and rvalue references to rvalues of compatible class type, as part of
+     DR391. */
+  if (compatible_p
+      && (lvalue_p
+	  || (flag_cpp0x
+	      && CLASS_TYPE_P (from))))

The compiler is still checking for a way to initialize a copy of B, even
though the copy is elided. You can verify this by adding a copy
constructor that does not bind to temporaries in A:

   A(A &);

If you add this to the test cases, you will get the same error as
before. But when you remove it, the compiler generates an implicit "A(A
const &)" copy constructor which allows compilation to succeed.
Previously it was illegal to bind "A const &" to a B object if B was not
copyable, but under DR391 that binding is allowed. That's all that's
going on here. 

> So, it looks to me like there's a little bit of work left to do on the
> rvalue references patch before it's ready for prime time, but it's
> really close...

I don't think this is the case. There's nothing mysterious going on
here, this behavior is by design. The test cases eithebr need to be be
modified on the C++0x branch or else not compiled in C++0x mode.

-  Russell Yanofsky (PGP ID: 0x5FAA0216)

Attachment: signature.asc
Description: This is a digitally signed message part

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]