how is this array subtyping inside struct (bug?) possible?
mw
mingwu at gmail.com
Mon Aug 10 18:29:56 UTC 2020
On Monday, 10 August 2020 at 12:03:06 UTC, Paul Backus wrote:
> On Monday, 10 August 2020 at 02:50:20 UTC, mw wrote:
>> On Monday, 10 August 2020 at 02:38:55 UTC, RazvanN wrote:
>>> On Sunday, 9 August 2020 at 21:12:58 UTC, mw wrote:
>>>
>>>> I'm *directly* access the underlying array, so why its
>>>> length changed to 0 after writeln?
>>>>
>>> You are accessing the underlying array after it was consumed.
>>> The line writeln(s0.fns) passes class, if you want to pass
>>> the underlying array you should type `writeln(so.fns.array)`
>>> and then it will not consume the array.
>>
>> I know that; and that's exactly I call it a subtyping bug:
>> i.e. directly access & access via subtyping behave differently:
>
> You are subtyping a value type (array) with a reference type
> (class). So when you directly access it, it's passed by value,
> but when you pass the subtype, it's passed by reference.
>
> In other words, using `alias this` does not create a *true*
> subtype (according to the Liskov substitution principle),
> because it allows you to change the way the type is copied from
> by-value to by-reference.
https://dlang.org/spec/arrays.html#dynamic-arrays
"Dynamic arrays consist of a length and a pointer to the array
data."
I've thought, D's dynamic array is implemented as:
``` /* this is C code */
struct {
T* ptr;
size_t length;
}
```
And now, it shows the length is changeable via its range
interface: so where on this range doc page this behavior on
length is mentioned?
https://dlang.org/phobos/std_range_primitives.html
"It defines the bidirectional and forward range primitives for
arrays: empty, front, back, popFront, popBack and save."
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...
}
```
More information about the Digitalmars-d
mailing list