October 25, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 ag0aep6g@gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |accepts-invalid CC| |ag0aep6g@gmail.com Severity|enhancement |normal -- |
October 26, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 Marco Leise <Marco.Leise@gmx.de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |Marco.Leise@gmx.de --- Comment #1 from Marco Leise <Marco.Leise@gmx.de> --- You are assuming that destructors are inherited and there is an implicit super-call, but they are actually chained and called one after another from outer to inner. Under the current language semantics this bug report is invalid. -- |
October 26, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #2 from Marco Leise <Marco.Leise@gmx.de> --- Here is the loop that iterates the inheritance chain from up to Object and calls destructors (if defined): https://github.com/D-Programming-Language/druntime/blob/v2.069.0-b2/src/rt/lifetime.d#L1366 -- |
October 26, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #3 from Andrei Alexandrescu <andrei@erdani.com> --- (In reply to Marco Leise from comment #1) > You are assuming that destructors are inherited and there is an implicit super-call, but they are actually chained and called one after another from outer to inner. Under the current language semantics this bug report is invalid. I agree I am using terminology loosely; newly introduced destructors don't only override the existing ones, they also call them. But I don't see how that makes the bug report invalid. -- |
October 27, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #4 from Marco Leise <Marco.Leise@gmx.de> --- The destructors do *neither* inherit *nor* call their parent destructors. Not as a matter of terminology, but because in D they are not called recursively, but in sequence, starting from the runtime type's dtor and working its way up the inheritance chain. Take a look at the druntime source I linked above and you will understand what happens. To make the bug report valid we would have to introduce destructor inheritance to the language to begin with. Right now the only functions affected by the destructor attributes would be the attribute-less external(C) functions `rt_finalize` and `rt_finalize2`. (In client code we call `rt_finalize` as `destroy(Object obj)` for deterministic object destruction). -- |
October 27, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #5 from Andrei Alexandrescu <andrei@erdani.com> --- (In reply to Marco Leise from comment #4) > The destructors do *neither* inherit *nor* call their parent destructors. Not as a matter of terminology, but because in D they are not called recursively, but in sequence, starting from the runtime type's dtor and working its way up the inheritance chain. Take a look at the druntime source I linked above and you will understand what happens. > > To make the bug report valid we would have to introduce destructor inheritance to the language to begin with. Right now the only functions affected by the destructor attributes would be the attribute-less external(C) functions `rt_finalize` and `rt_finalize2`. (In client code we call `rt_finalize` as `destroy(Object obj)` for deterministic object destruction). I understand what happens technically (each dtor is distinct, and code external to the destructor calls them all). What happens conceptually is that destructors in derived classes both override and call destructors in base classes. There is no need to change the language to make the bug report valid. Destructors must typecheck as if they override and call the base class destructors. -- |
October 27, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #6 from Marco Leise <Marco.Leise@gmx.de> --- I'd agree with you if this was all not observable, but your change causes friction that I object against. It should be either inheritance all the way or just sequential calls as right now. Otherwise destructors will be perceived as inheriting while type-checking and as stand-alone when called directly. To illustrate this: import core.stdc.stdio; void main() { // Get a vanilla 'Ext' object without calling // constructors and spoiling the output. void[__traits(classInstanceSize, Ext)] buf = void; buf[] = typeid(Ext).init[]; // Show constructor/destructor semantics. Ext ext = cast(Ext) buf.ptr; ext.__ctor(); ext.__dtor(); } class Base { void* v; this() { printf("Base ctor\n"); } ~this() { printf("Base dtor\n"); } // never called } class Ext : Base { this() { printf("Ext ctor\n"); } ~this() @nogc nothrow { printf("Ext dtor\n"); } } Prints: Base ctor Ext ctor Ext dtor In particular in this example with D's semantics it is correct to have Ext's destructor be @nogc nothrow while the Base destructor is not. It may be surprising depending on programming language background, but at least it is consistently implemented as far as I can tell. -- |
October 27, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #7 from Andrei Alexandrescu <andrei@erdani.com> --- @mleise that is surprising. I assumed calling __dtor also invokes the base destructors. What is the canonical way to destroy a D class properly? (This bug report stands.) -- |
October 27, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #8 from Marco Leise <Marco.Leise@gmx.de> --- We "finalize" them through the helper function `rt_finalize` mentioned earlier, which calls the __dtor's in sequence and is the only place that also handles destruction of the hidden "monitor" field if it was used. It is wrapped in object.d as: void destroy(T)(T obj) if (is(T == class)) { rt_finalize(cast(void*)obj); } destroy() complete object finalization + memory reinitialized to .init __xdtor same as __dtor + destroys any RAII members __dtor the ~this() function as defined in the source (That's how I remember it. May be inaccurate.) -- |
October 27, 2015 [Issue 15246] Destructor inheritance doesn't inherit attributes properly | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=15246 --- Comment #9 from Andrei Alexandrescu <andrei@erdani.com> --- That's quite the bummer because rt_finalize in all likelihood doesn't know anything about attributes. -- |
Copyright © 1999-2021 by the D Language Foundation