digitalmars.D.learn - How should class objects created in betterC be destroyed
- zoe (6/6) Nov 05 2023 I customized object.d in -betterc mode and created NEW templates,
- Imperatorn (2/8) Nov 05 2023 Do you have the implementation somewhere?
- zoe (4/12) Nov 05 2023 I just define an empty object class, select the object.d file at
- zoe (105/113) Nov 05 2023 // app.d
- Paul Backus (29/35) Nov 06 2023 Unfortunately, D classes cannot have virtual destructors, so
I customized object.d in -betterc mode and created NEW templates, with modules I can seemingly create classes without extern(C++) mode, and type conversions in function calls seem to work fine. But when destroy doesn't find a way to call the __xtdor() method of the corresponding subclass, is there any way to execute __xtdor() correctly
Nov 05 2023
On Monday, 6 November 2023 at 05:30:02 UTC, zoe wrote:I customized object.d in -betterc mode and created NEW templates, with modules I can seemingly create classes without extern(C++) mode, and type conversions in function calls seem to work fine. But when destroy doesn't find a way to call the __xtdor() method of the corresponding subclass, is there any way to execute __xtdor() correctlyDo you have the implementation somewhere?
Nov 05 2023
On Monday, 6 November 2023 at 05:52:18 UTC, Imperatorn wrote:On Monday, 6 November 2023 at 05:30:02 UTC, zoe wrote:I just define an empty object class, select the object.d file at compile time, and you can use the class, and function parameters can also use the interfaceI customized object.d in -betterc mode and created NEW templates, with modules I can seemingly create classes without extern(C++) mode, and type conversions in function calls seem to work fine. But when destroy doesn't find a way to call the __xtdor() method of the corresponding subclass, is there any way to execute __xtdor() correctlyDo you have the implementation somewhere?
Nov 05 2023
On Monday, 6 November 2023 at 05:52:18 UTC, Imperatorn wrote:On Monday, 6 November 2023 at 05:30:02 UTC, zoe wrote:// app.d module app; import core.stdc.stdio; interface L { void interfaceTest(); } class Base : L { void interfaceTest() { puts("call base"); } ~this() { puts("destory base"); } } class Test : Base { int i; int y; override void interfaceTest() { puts("call test"); } ~this() { super.__xdtor(); puts("destory test"); } } public void test2(ref Base l) { l.interfaceTest(); l.destroy(); } public void test() { Base t = NEW!Test(); test2(t); } extern (C) int main() { test(); return 0; } // object.d module object; import core.stdc.stdlib; import core.stdc.string; import core.stdc.stdio; alias size_t = typeof(int.sizeof); alias ptrdiff_t = typeof(cast(void*) 0 - cast(void*) 0); alias sizediff_t = ptrdiff_t; // For backwards compatibility only. // /** // * Bottom type. // * See $(DDSUBLINK spec/type, noreturn). // */ alias noreturn = typeof(*null); alias hash_t = size_t; // For backwards compatibility only. alias equals_t = bool; // For backwards compatibility only. alias string = immutable(char)[]; alias wstring = immutable(wchar)[]; alias dstring = immutable(dchar)[]; T NEW(T, Args...)(auto ref Args args) { enum tsize = __traits(classInstanceSize, T); T t = () trusted { import core.stdc.stdlib; auto _t = cast(T) malloc(tsize); if (!_t) return null; import core.stdc.string : memcpy; memcpy(cast(void*) _t, __traits(initSymbol, T).ptr, tsize); return _t; }(); if (!t) return null; t.__ctor(args); return t; } void destroy(T)(ref T instance) { static if (__traits(hasMember, T, "__xdtor") && __traits(isSame, T, __traits(parent, instance.__xdtor))) instance.__xdtor(); () trusted { import core.stdc.stdio; free(cast(void*) instance); }(); instance = null; } class Object { this() { } ~this() { } } // dmd -betterC .\app.d .\object.d or ldmd2 -betterC -m64 .\app.d .\object.d The destroy method does not find exactly what the subclass object should beI customized object.d in -betterc mode and created NEW templates, with modules I can seemingly create classes without extern(C++) mode, and type conversions in function calls seem to work fine. But when destroy doesn't find a way to call the __xtdor() method of the corresponding subclass, is there any way to execute __xtdor() correctlyDo you have the implementation somewhere?
Nov 05 2023
Please tag your code accordingly, as is it's unreadable ```D // your code here ``` (tick the "Enable Markdown" too, next to the Send button)
Nov 06 2023
Here is how adam seems to be doing it: https://github.com/adamdruppe/webassembly/blob/731a7033174127c0a6dd4f23eabdb440adab286b/arsd-webassembly/object.d#L650-L681 Specially here: ```D void destroy(bool initialize = true, T)(T obj) if (is(T == class)) { (..) else { // Bypass overloaded opCast auto ptr = (() trusted => *cast(void**) &obj)(); rt_finalize2(ptr, true, initialize); } } ``` and for interface: ```D cast(Object)obj ``` But i suspect you'll have to implement the whole typeinfo
Nov 06 2023
On Monday, 6 November 2023 at 16:08:41 UTC, ryuukk_ wrote:Here is how adam seems to be doing it: https://github.com/adamdruppe/webassembly/blob/731a7033174127c0a6dd4f23eabdb440adab286b/arsd-webassembly/object.d#L650-L681 Specially here: ```D void destroy(bool initialize = true, T)(T obj) if (is(T == class)) { (..) else { // Bypass overloaded opCast auto ptr = (() trusted => *cast(void**) &obj)(); rt_finalize2(ptr, true, initialize); } } ``` and for interface: ```D cast(Object)obj ``` But i suspect you'll have to implement the whole typeinfoThanks, I found out later that I couldn't use the cast keyword
Nov 06 2023
On Monday, 6 November 2023 at 05:30:02 UTC, zoe wrote:I customized object.d in -betterc mode and created NEW templates, with modules I can seemingly create classes without extern(C++) mode, and type conversions in function calls seem to work fine. But when destroy doesn't find a way to call the __xtdor() method of the corresponding subclass, is there any way to execute __xtdor() correctlyUnfortunately, D classes cannot have virtual destructors, so TypeInfo is the only way to find the correct derived class destructor to call at runtime. I think the best you can do is implement your own virtual destructors, and your own `destroy` function that knows how to call them; for example: ```d interface BettercDestructible { void destruct() nothrow nogc; } class MyClass : BettercDestructible { // ... override void destruct() { // destructor implementation here } ~this() { this.destruct(); } } void destroy(BettercDestructible obj) { obj.destruct(); } ``` Of course, for classes that don't implement `BettercDestructible`, you're still out of luck, but it's better than nothing.
Nov 06 2023