Thread overview
Disallow destroy(structPtr)?
Feb 20, 2015
Nick Treleaven
Feb 20, 2015
Ali Çehreli
February 20, 2015
Hi,

The following code is supposed to destroy the struct instance:

    import std.stdio;
    struct S{
        ~this(){"destruct".writeln;}
        }
    auto p = new S;
    destroy(p);
    "end".writeln;

It works correctly if I use destroy(*p), but the above code could perhaps be statically rejected by object.destroy to help prevent bugs. Currently, the pointer p is set to null without calling the destructor (with recent dmd the destructor is called, but only after "end" is printed).

Here is the destroy overload:

void destroy(T)(ref T obj)
    if (!is(T == struct) && !is(T == interface) && !is(T == class) && !_isStaticArray!T)
{
    obj = T.init;
}
February 20, 2015
On 2/20/15 1:05 PM, Nick Treleaven wrote:
> Hi,
>
> The following code is supposed to destroy the struct instance:
>
>      import std.stdio;
>      struct S{
>          ~this(){"destruct".writeln;}
>          }
>      auto p = new S;
>      destroy(p);
>      "end".writeln;
>
> It works correctly if I use destroy(*p), but the above code could
> perhaps be statically rejected by object.destroy to help prevent bugs.
> Currently, the pointer p is set to null without calling the destructor
> (with recent dmd the destructor is called, but only after "end" is
> printed).
>
> Here is the destroy overload:
>
> void destroy(T)(ref T obj)
>      if (!is(T == struct) && !is(T == interface) && !is(T == class) &&
> !_isStaticArray!T)
> {
>      obj = T.init;
> }

I'm beginning to think this is the right thing to do. It confuses so many people, and setting a pointer/class reference/array to null is easy enough without needing a special function to do it. In other words, if you are using destroy, you aren't just trying to nullify a pointer. You want to destroy what the pointer represents.

The only problem is, how does this affect existing code?

-Steve
February 20, 2015
On 02/20/2015 12:30 PM, Steven Schveighoffer wrote:

> On 2/20/15 1:05 PM, Nick Treleaven wrote:

>> It works correctly if I use destroy(*p), but the above code could
>> perhaps be statically rejected by object.destroy to help prevent bugs.

> I'm beginning to think this is the right thing to do. It confuses so
> many people, and setting a pointer/class reference/array to null is easy
> enough without needing a special function to do it. In other words, if
> you are using destroy, you aren't just trying to nullify a pointer. You
> want to destroy what the pointer represents.
>
> The only problem is, how does this affect existing code?

And templated containers...

Despite the issue, I favor the current behavior partly because I am used to it from C++: A pointer going out of scope does not delete what it points to. (It can't do that because the pointer does not know about the object's ownership.)

Ali