On Borrow Checking
Dennis
dkorpel at gmail.com
Tue May 13 11:13:41 UTC 2025
On Monday, 12 May 2025 at 19:28:10 UTC, Walter Bright wrote:
> This comes about because `old`, being declared after `ctx`, has
> a shorter lifetime than `ctx`. If `old` has a destructor, that
> destructor will run before `ctx`s destructor, and `ctx` will be
> referring to an invalid instance of `old`.
You can't free a pointer that has aliases in `@safe` code.
Therefore you can't simply have a destructor that performs a
free(), the struct that has it needs to prevent aliasing by
disabling copies with `@disable this(this)`, or by providing a
copy constructor that duplicates the pointer. Otherwise you allow
memory corruption:
```D
import std.stdio;
@safe:
struct S
{
int* x;
~this() scope @trusted { writefln("~this(): free(%s)",
cast(void*) x); }
}
void f(ref scope S ctx)
{
{
auto old = ctx;
}
writefln("use %s", cast(void*) ctx.x);
}
void main()
{
scope S s = S(new int(38));
f(s);
}
```
This prints:
```
~this(): free(7F8D32557000)
use 7F8D32557000
~this(): free(7F8D32557000)
```
Both a 'use after free' and a 'double free'! But if you add
`this(this) scope { x = new int(*x); }` to S, it works out.
> If S does not have a destructor, does that make the error a
> false positive or not? I decided that the existence of a
> destructor should not change the scoping rules.
I agree with that, but in light of the above, I don't think a
copy of a scope pointer should have its lifetime shortened to the
destination variable.
It may be by design, but it's a false positive in the sense that
it leads to unnecessary refactoring (like
https://github.com/dlang/phobos/pull/8125), and to unnecessary
`@trusted` code. The `ctx = old` example I gave is reduced from
my actual code:
https://github.com/dkorpel/ctod/blob/1651fb4e31095e0cf5e0c4524149bdc2bcc7539e/source/ctod/cdeclaration.d#L231
If you have an alternate way to write that in a `@safe` way, I'd
love to hear it.
> BTW, thank you for your post. It's informative and excellent.
:)
More information about the Digitalmars-d
mailing list