Thread overview
Is the `in` operator @safe?
6 days ago
Simen Kjærås
6 days ago
Kagamin
6 days ago
Dukc
February 11
After a quick look it seems like the `in` operator may return a pointer that becomes invalid when an AA is resized:

https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L601
https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L114
https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L193

Yet you can use `in` in @safe functions and keep the pointer around. Is my assessment correct, or did I overlook anything? If so, I'll open a bug report (I didn't find one already open for that, but maybe I searched the wrong keywords).
6 days ago
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
> After a quick look it seems like the `in` operator may return a pointer that becomes invalid when an AA is resized:
>
> https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L601
> https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L114
> https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L193
>
> Yet you can use `in` in @safe functions and keep the pointer around. Is my assessment correct, or did I overlook anything? If so, I'll open a bug report (I didn't find one already open for that, but maybe I searched the wrong keywords).

This quick test indicates that the pointer doesn't get invalidated:

@safe unittest {
    import std.stdio : writeln;
    int[int] arr;
    arr[0] = 0;
    int* p = 0 in arr;
    int n = 1;
    while (p == (0 in arr)) {
        if (n % 1000 == 0) n.writeln;
        arr[n++] = 0;
    }
    n.writeln;
}

It crashes with an OutOfMemoryError after allocating ~27M elements on my machine.

It seems the AA is actually holding a list of Buckets, with each bucket containing a pointer to the actual element. When it's resize only the bucket list is affected, and the element pointers are still valid.

--
  Simen
6 days ago
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
> After a quick look it seems like the `in` operator may return a pointer that becomes invalid when an AA is resized

Memory allocated from GC is valid, that's how GC is part of the safety system.
6 days ago
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
> Yet you can use `in` in @safe functions and keep the pointer around. Is my assessment correct, or did I overlook anything? If so, I'll open a bug report (I didn't find one already open for that, but maybe I searched the wrong keywords).

I believe the memory referenced to by AA is garbage collected, not memory managed by ownership. As long as the memory you keep the pointer at is scanned by the collector, the AA content should not get freed.