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

Andrei Alexandrescu SeeWebsiteForEmail at erdani.com
Fri Nov 12 16:43:46 UTC 2021


On 2021-11-11 22:41, tsbockman wrote:
> 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!
> }
> ```

Interesting, thanks. I submitted 
https://issues.dlang.org/show_bug.cgi?id=22507.


More information about the Digitalmars-d mailing list