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

Douglas Gregor dgregor at apple.com
Fri Mar 27 14:26:10 PDT 2009


On Mar 27, 2009, at 2:19 PM, Howard Hinnant wrote:

> On Mar 27, 2009, at 4:42 PM, Sebastian Redl wrote:
>
>> 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.
>
> I don't know if it was intentional or not either.

It was intentional that I didn't want to apply a conversion to an  
lvalue to turn it into an rvalue for binding to an rvalue reference.  
That's one of the things that got us in trouble with shared_ptr's swap  
when it had an rvalue-reference version. As Howard notes in his  
examples, having that conversion can lead to some confusing behavior.

I didn't actually think about the case of a user-defined conversion an  
rvalue reference, but what the WP says now feels right, for the  
reasons that you've both mentioned.

	- Doug



More information about the cfe-commits mailing list