how is this array subtyping inside struct (bug?) possible?
mw
mingwu at gmail.com
Mon Aug 10 19:39:28 UTC 2020
On Monday, 10 August 2020 at 19:30:18 UTC, Steven Schveighoffer
wrote:
> On 8/10/20 2:36 PM, mw wrote:
>> On Monday, 10 August 2020 at 18:29:56 UTC, mw wrote:
>>> and where in this doc on range:
>>>
>>> https://tour.dlang.org/tour/en/basics/ranges
>>>
>>> it is mentioned that: the length property of the range will
>>> be changed after the range is "consumed" by foreach loop?
>>>
>>> ```
>>> foreach (element; range)
>>> {
>>> // Loop body...
>>> }
>>> it's internally rewritten similar to the following:
>>>
>>> for (auto __rangeCopy = range;
>>> !__rangeCopy.empty;
>>> __rangeCopy.popFront())
>>> {
>>> auto element = __rangeCopy.front;
>>> // Loop body...
>>> }
>>> ```
>>
>> And wait, ... did I saw "__rangeCopy" here? it should be a
>> *copy*?!
>>
>>
>
> In your code, the type of "range" is SharedArray!(string) which
> is a class or *reference type*.
>
> So let's follow along what happens:
>
> SharedArray!(string) fns;
> for(auto __rangeCopy = fns;
>
> // the above makes a copy of a *class reference*, which means
> it does not make a copy of the *array data* or even the array
> reference. It's like copying a pointer to the array.
>
> !__rangeCopy.empty;
>
> // SharedArray(T) does not have empty member, so this forwards
> to the array, it's like saying:
> // !__rangeCopy.array.empty
>
> __rangeCopy.popFront())
>
> // This is equivalent to __rangeCopy.array.popFront, which
> alters the array inside the ONE SHARED class instance.
This still doesn't explain why the underlying array.length is
modified after the range to consumed; too much black magic is
happening here.
> How to fix? extract the array before iterating:
>
> writeln(s0.fns.array);
This defeats the purpose, i.e. the convenience that subtyping
mechanism supposed to provide.
More information about the Digitalmars-d
mailing list