How to call destroy() in @nogc?

Steven Schveighoffer schveiguy at gmail.com
Tue May 24 14:11:57 UTC 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- at 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


More information about the Digitalmars-d-learn mailing list