[cfe-commits] r67059 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ lib/AST/ lib/CodeGen/ lib/Sema/ test/Parser/ test/SemaCXX/

Sebastian Redl sebastian.redl at getdesigned.at
Fri Mar 27 13:42:04 PDT 2009


Howard Hinnant wrote:
> On Mar 23, 2009, at 1:18 PM, Douglas Gregor wrote:
>
>   
>> Yes, both are well-formed and both mean different things. The first  
>> one causes a direct binding (that's [dcl.init.ref]p5b1sb2), while  
>> the second one binds to a temporary.
>>
>> You know, I completely screwed up the example. I meant test() to be:
>>
>>  void test(B b) {
>>    A &ar = b; // ill-formed
>>  }
>>
>> *sigh*, and I think I've answer my own question. Sorry for the noise.
>>     
>
> I was wondering.  Thanks for the clarification.  Yeah, with that  
> change I agree:  ill-formed.
>   
Interestingly enough, by following the rules of N2857 (March draft) to
the letter, this too is invalid:

struct B { operator A&&(); };

B b;
A &&ar = b;

The reason is in the bullet ordering. [dcl.init.ref]p5 says:

-- If the reference is an lvalue reference [...]
-> does not apply
-- Otherwise, the reference shall be an lvalue reference to a
non-volatile const type, or the reference shall be an rvalue reference
and the initializer expression shall be an rvalue.
-> b is an lvalue, so the program is ill-formed.

Any sub-points of the second bullet no longer matter.

I don't know if this is intentional. It feels right that only an rvalue
B should allow this conversion to be applied (after all, if that A&& is
moved from, most likely this affects B's state), but at the same time I
think invoking a user-defined conversion to a reference type on a
temporary and then keeping that reference is a very unsafe thing to do.

Sebastian



More information about the cfe-commits mailing list