D needs first-class lifetimes before it can get ownership and borrowing
Nick Treleaven
nick at geany.org
Sat Aug 10 17:38:43 UTC 2019
On Saturday, 10 August 2019 at 13:30:17 UTC, Olivier FAURE wrote:
> I've been trying to nail down the semantics of my in-progress
> DIP for a `unique` qualifier, and I couldn't come up with
> coherent rules for double-indirection.
>
> To give you an shortened example of the problem, contemplate
> this:
>
> int* gptr;
>
> struct SmartPtr {
> int* ptr;
>
> @safe:
> ~this() { reset(); }
> @trusted:
> void init() { ptr = cast(int*)malloc(int.sizeof); *ptr
> = 0; }
> void reset() { free(ptr); ptr = null; }
>
> @safe:
> ref int get() return { assert(ptr); return *ptr; }
>
> void borrow() { gptr = this.ptr; }
> }
>
> @safe
> void main() {
> SmartPtr s;
> s.init();
> s.borrow();
> s.reset();
> *gptr = 1; // Memory corruption
> }
>
> The problem above is that, under DIP-1000, the compiler assumes
> `borrow()` doesn't escape any data, because it takes `this` by
> ref; and yet it escapes this.ptr, because there's no way to
> mark this.ptr as scope.
We could allow scope fields:
struct SmartPtr {
scope int* ptr
> As long as borrow() is @safe, there's no way reset() can be
> @trusted.
That use of @trusted requires @safe code inside the struct (and
in the defining module due to field access) to form part of the
@trusted contract.
scope fields would lessen the burden of @trusted and allow
encapsulated pointers. But there still won't be an error if you
don't use scope for the ptr field.
More information about the Digitalmars-d
mailing list