digitalmars.D.learn - How to call destroy() in nogc?
- cc (32/32) May 23 2022 ```d
- Tejas (2/7) May 23 2022 FWIW your code will compile if you add `extern(C++)` to `Foo`
- cc (14/22) May 23 2022 Interesting, thanks. I noticed something similar when trying to
- Steven Schveighoffer (9/44) May 24 2022 It's because destroy calls the destructor without any attribute
- Adam Ruppe (14/17) May 24 2022 It actually has nothing to do with Object. It doesn't have a
```d import core.memory; import core.stdc.stdlib : malloc, free; import core.lifetime : emplace; T NEW(T, Args...)(auto ref Args args) /* nogc*/ if (is(T == class)) { enum size = __traits(classInstanceSize, T); void* mem = malloc(size); scope(failure) free(mem); return mem !is null ? emplace!T(mem[0..size], args) : null; } void FREE(T)(ref T obj) nogc if (is(T == class)) { auto mem = cast(void*) obj; scope(exit) free(mem); destroy(obj); obj = null; } class Foo { ~this() nogc {} } void main() { auto foo = NEW!Foo; FREE(foo); } ``` ``` Error: ` nogc` function `nogctest.FREE!(Foo).FREE` cannot call non- nogc function `object.destroy!(true, Foo).destroy` ``` Is this not currently possible? Found this thread: https://forum.dlang.org/thread/zanuuhzmqxljadcexmgv forum.dlang.org?page=1 is it still unresolved?
May 23 2022
On Tuesday, 24 May 2022 at 02:29:38 UTC, cc wrote:```d import core.memory; import core.stdc.stdlib : malloc, free; import core.lifetime : emplace; [...]FWIW your code will compile if you add `extern(C++)` to `Foo`
May 23 2022
On Tuesday, 24 May 2022 at 02:55:06 UTC, Tejas wrote:On Tuesday, 24 May 2022 at 02:29:38 UTC, cc wrote:Interesting, thanks. I noticed something similar when trying to call malloc in a pure function... std.internal.memory: ```d extern (C) nogc nothrow pure private { pragma(mangle, "malloc") void* fakePureMalloc(size_t) safe; pragma(mangle, "calloc") void* fakePureCalloc(size_t nmemb, size_t size) safe; pragma(mangle, "realloc") void* fakePureRealloc(return scope void* ptr, size_t size) system; } ``````d import core.memory; import core.stdc.stdlib : malloc, free; import core.lifetime : emplace; [...]FWIW your code will compile if you add `extern(C++)` to `Foo`
May 23 2022
On 5/23/22 10:29 PM, cc wrote:```d import core.memory; import core.stdc.stdlib : malloc, free; import core.lifetime : emplace; T NEW(T, Args...)(auto ref Args args) /* nogc*/ if (is(T == class)) { enum size = __traits(classInstanceSize, T); void* mem = malloc(size); scope(failure) free(mem); return mem !is null ? emplace!T(mem[0..size], args) : null; } void FREE(T)(ref T obj) nogc if (is(T == class)) { auto mem = cast(void*) obj; scope(exit) free(mem); destroy(obj); obj = null; } class Foo { ~this() nogc {} } void main() { auto foo = NEW!Foo; FREE(foo); } ``` ``` Error: ` nogc` function `nogctest.FREE!(Foo).FREE` cannot call non- nogc function `object.destroy!(true, Foo).destroy` ``` Is this not currently possible? Found this thread: https://forum.dlang.org/thread/zanuuhzmqxljadcexmgv forum.dlang.org?page=1 is it still unresolved?It's because destroy calls the destructor without any attribute requirements aside from nothrow. https://github.com/dlang/druntime/blob/bdeee862aaa125e75aebc3118a43d2d5e5ee954d/src/object.d#L4431-L4453 Here is the definition of `rt_finalize2`: https://github.com/dlang/druntime/blob/bdeee862aaa125e75aebc3118a43d2d5e5ee954d/src/rt/lifetime.d#L1402 Note it has no idea what the real object type is at this point, just that it is an Object (which does not have a nogc destructor). -Steve
May 24 2022
On Tuesday, 24 May 2022 at 14:11:57 UTC, Steven Schveighoffer wrote:Note it has no idea what the real object type is at this point, just that it is an Object (which does not have a nogc destructor).It actually has nothing to do with Object. It doesn't have a destructor at all, so there's no problem calling it from any context. The real problem is that destructors don't actually use the virtual machinery and call super(), meaning it is impossible to tell at compile time what they're doing at all. I know I wrote at length about this somewhere but can't find it right now. Probably in the chatroom. But even if you know static type, you can't make assumptions about the dynamic type since destructors (for no good reason tbh) don't follow the same rules as other virtual methods, despite the spec saying they are virtual.
May 24 2022