return by auto ref horribly broken ?

monarch_dodra monarchdodra at gmail.com
Tue Feb 19 02:16:46 PST 2013


On Monday, 18 February 2013 at 21:32:13 UTC, Zach the Mystic 
wrote:
> On Monday, 18 February 2013 at 11:10:38 UTC, monarch_dodra 
> wrote:
>> I think I'm opening a can of worms here, in regards to 
>> inferring the escape of references, but a quick investigation 
>> showed me that return by auto-ref is horribly broken.
>>
>> Basically, the only thing it does is check if the very last 
>> value it returns is a ref, but a ref to what? The 
>> possibilities of returning a ref to a local are HUGE. For 
>> example, simple returning the index of a tuple, or of a static 
>> array, and you're in it deep:
>>
>> //----
>> import std.typecons;
>>
>> auto ref foo(T)(auto ref T t)
>> {
>>    return t[0];
>> }
>>
>> void main()
>> {
>>    int* p = &foo(tuple(1, 2));
>> }
>> //----
>>
>> Here, both foo will return a ref to a local. But the compiler 
>> won't see, and more importantly, it gets blind sided because 
>> it *can't* see it (AFAIK).
>
> If you take the address of a value returning type, you must 
> either ban doing it outright or treat the assigned pointer as 
> dangerous. To take the address of a value type returned from 
> the stack is especially dangerous - I can see banning it 
> outright and I don't know what the spec currently says about 
> this.

What I wanted to show was that since the code compiled, foo 
returned by ref. At this point, the assigned pointer shouldn't 
even be considered as "dangerous", since we are already in 
undefined behavior.

I could have replaced the code with:
"int a = foo(tuple(1, 2));"

The bug would have been less obvious, but there are chances this 
creates a (very) hard to catch bug.

> My assumption would be that the only legal version of this 
> would be the one which returns 'ref'. But tuple(1,2) is an 
> rvalue struct type if I'm not mistaken, which means it would be 
> passed as a value. The compiler should not allowed a type 
> passed as a value (or any part of that value) to be returned as 
> a reference, right? So I don't see a way to take the address of 
> this result legally. I don't think it should return a reference 
> at all with 'tuple(1,2)'. That's all I know.

Indeed, there is no way to take the address of the returned value 
in this case, since it shouldn't return by ref.

But it does...


More information about the Digitalmars-d mailing list