Challenge: write a reference counted slice that works as much as possible like a built-in slice

tsbockman thomas.bockman at gmail.com
Fri Nov 12 03:41:58 UTC 2021


On Thursday, 11 November 2021 at 23:17:53 UTC, Andrei 
Alexandrescu wrote:
> On 2021-11-08 20:14, tsbockman wrote:
>> With current language semantics, the destructor (and any other 
>> similar operations, such as reassignment) of the reference 
>> type must be `@system` to prevent misuse of the destructor in 
>> `@safe` code.
>>      https://issues.dlang.org/show_bug.cgi?id=21981
>> 
>> The solution to this problem is to introduce some way of 
>> telling the compiler, "this destructor is `@safe` to call 
>> automatically at the end of the object's scope, but `@system` 
>> to call early or manually."
>
> This I'm not worried about. `@trusted` should be fine in 
> low-level code, no? `destroy` is not safe. What am I missing?

In the program below, if `Owner.__dtor` is `@system`, then 
`@safe` code like `main` can't instantiate `Owner`.

But, if `Owner.__dtor` is `@trusted`, then memory safety can be 
violated with a "use after free".

```D
module app;

struct Owner {
     import core.stdc.stdlib : malloc, free;

     private int* x;

     this(const(int) x) @trusted {
         this.x = cast(int*) malloc(int.sizeof);
         *(this.x) = x;
     }
     inout(int*) borrow() return inout @safe {
         return x; }
     ~this() @trusted {
         free(x);
         x = null;
     }
}

void main() @safe {
     import std.stdio : writeln;

     Owner owner = 1;
     scope x = owner.borrow;
     writeln(*x);
     destroy!false(owner); // owner.__dtor(); // is also @safe
     writeln(*x += 1); // use after free!
}
```


More information about the Digitalmars-d mailing list