[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