should destroy!false be @system?

Steven Schveighoffer schveiguy at gmail.com
Thu Feb 23 17:01:05 UTC 2023


Let's say you have a struct that manages a malloc'd resource:

```d
struct S(T)
{
    private T* val;
    @disable this(this);
    this(T val) {
       this.val = cast(T*)malloc(T.sizeof);
       *this.val = val;
    }
    ~this() {
       free(val);
    }
    ref T get() { return *val; }
}
```

Now, if you just use an S!T on the stack, it works as expected.

But what happens if you destroy `s`? If you do, then it will call the 
destructor a *second time* when the struct goes out of scope. However, 
`destroy` will reinitialize the value with the `.init` value.

What about `destroy!false`? This *doesn't* initialize the value back to 
an .init state, and so leaves a dangling pointer in the above type.

This is a fuzzy area for me. I tend to *always* nullify any resource as 
soon as I destroy it, this way I don't accidentally screw it up later 
(old habit). But is that the correct expectation for a struct that has 
been destroyed? Is it reasonable to expect that once a struct is 
destroyed, it can never be used again (even to call the destructor)?

My thought is that, for a struct with a destructor:

a) the destructor should *always* be callable on its `.init` value.
b) a struct that has been destroyed where its lifetime lives on should 
be overwritten with its '.init' value.
c) if destroyed without overwriting with `.init` value, the program 
should make sure a second destructor call should not be allowed to 
happen in @safe code.

is c) reasonable? Do we need to deprecate @safe calls to `destroy!false` 
for types that have destructors?

-Steve


More information about the Digitalmars-d mailing list