www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How should class objects created in betterC be destroyed

reply zoe <fionalde outlook.com> writes:
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
next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
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() correctly
Do you have the implementation somewhere?
Nov 05 2023
next sibling parent zoe <fionalde outlook.com> writes:
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 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
Do you have the implementation somewhere?
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 interface
Nov 05 2023
prev sibling parent reply zoe <fionalde outlook.com> writes:
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 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
Do you have the implementation somewhere?
// 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 be
Nov 05 2023
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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
parent zoe <fionalde outlook.com> writes:
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 typeinfo
Thanks, I found out later that I couldn't use the cast keyword
Nov 06 2023
prev sibling parent Paul Backus <snarwin gmail.com> writes:
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() correctly
Unfortunately, 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