D's Destructors are What Scott Meyers Warned Us About

sarn sarn at theartofmachinery.com
Wed May 23 23:11:12 UTC 2018


On Wednesday, 23 May 2018 at 13:12:57 UTC, Steven Schveighoffer 
wrote:
> On 5/22/18 9:59 PM, sarn wrote:
>> * Some code uses __dtor as a way to manually run cleanup code 
>> on an object that will be used again.  Putting this cleanup 
>> code into a normal method will cause fewer headaches.
>
> Using __dtor is a very bad idea in almost all cases. Putting 
> cleanup code into a normal function can have some of the same 
> pitfalls, however (what if you forget to call the super version 
> of the method?). The only *correct* way to destroy an object is 
> to follow the runtime's example or call the function directly.
>
> The destructor also has the nice feature of being called when 
> the struct goes out of scope.
>
> Best advice -- just use destroy on types to clean them up.

Here's an example of what I'm talking about:
https://github.com/dlang/phobos/blob/master/std/signals.d#L230

It's running __dtor manually just to run some code that happens 
to be in the destructor.  It's obviously not meant to run any 
other destructors (at least, the documentation doesn't say "Use 
this mixin in your object and then calling disconnectAll() will 
destroy everything in your object.").

It's a broken design pattern, but existing code is doing it.  (As 
I said, I reviewed a lot of D packages, and I don't have time to 
file bug reports or PRs for each one.)

> But this is not necessarily the definition of POD. Generally 
> this means it has no postblit, and some people may even be 
> expecting such a thing to have no methods as well. So I'm not 
> sure we want to add such a definition to the library.

The common case is that some data types can be blitted around as 
raw memory without worrying about destructors, postblits, or 
whatever is added to the language in future.  This is the thing 
that seems to matter.  (Have you seen any code that needs to care 
if a struct has methods?  It sounds like a very special case that 
can still be handled using current compile-time reflection 
anyway.)

__traits(isPOD) seems to do the job, and is a lot better than the 
ad hoc implementations I've seen.  We should encourage people to 
use it more often.



More information about the Digitalmars-d mailing list