D's Destructors are What Scott Meyers Warned Us About
sarn
sarn at theartofmachinery.com
Sun May 27 22:27:52 UTC 2018
On Sunday, 27 May 2018 at 09:55:56 UTC, Mike Franklin wrote:
> TypeInfo has become my nemesis. I've been trying to replace
> runtime hooks that depend on TypeInfo with templates that can
> get their information at compile-time, but I'm running into all
> sorts of problems. e.g. Did you know array.length can be set
> in @safe nothrow pure code, but it lowers to runtime functions
> that are neither @safe, nothrow, nor pure?
Ouch.
> Anyway, I'm getting better at modifying the compiler/runtime
> interface. If we can come up with a solution to this mess, and
> I can understand it, I might be able to implement it.
I've been meaning to learn more about how the compiler/runtime
interface works myself but still haven't got around it. I'm
probably going to learn a lot by looking at your PRs.
I've been thinking this through a bit, and here's what I've got
so far:
At first I obviously wanted an all-round "just works" low-level
interface for destroying objects. But after looking at how
people are using __dtor/__xdtor in real code, and looking at the
PRs for destroy(), it's obvious that there's a lot of
disagreement about what that means. Let's leave that topic for
now.
If we just focus on fixing classes, we can add, say, __vdtor (I
really don't care much about the name, BTW). This needs to be a
normal virtual function in the vtable (preferably in a way that's
compatible with C++ ABIs) that runs the user-defined destructor
code, then recursively calls destructors for members and base
classes.
The generation of __vdtor also needs a special case to make
attributes work. Something like "an empty destructor has
attributes inferred like templated functions are, restricted by
any of its bases". For example, this needs to work:
extern(C++)
{
class Base
{
// Virtual
~this() @nogc
{
}
}
class Derived
{
// Not marked pure but is still @nogc
// (NB: explicitly marking @nogc isn't needed in current
language)
override ~this() @nogc
{
}
}
class Derived2 : Derived
{
override ~this() @nogc pure
{
// Marked pure, but still recurses to empty destructors
in Derived and Base
}
}
}
Right now __vdtor would need to be implemented with a thunk that
wraps around __xdtor (like I implemented here:
https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.html). But if __vdtor is implemented, the D runtime code can be simplified to use __vdtor for classes, then hopefully we can deprecate and remove __dtor and __xdtor for classes, and then __vdtor can become the native destructor implementation.
More information about the Digitalmars-d
mailing list