Destructors can't be @nogc?
user1234
user1234 at 12.de
Sun Jul 25 01:17:06 UTC 2021
On Friday, 23 July 2021 at 20:24:02 UTC, Jim wrote:
> Hello,
>
> I've been playing with D and trying to understand how to work
> with @nogc. I must be doing something wrong, because even
> though I tagged the destructor for my class `@nogc`, I'm
> getting the following error: `.\min.d(27): Error: "@nogc"
> function "D main" cannot call non- at nogc function
> "object.destroy!(true, TestClass).destroy`
>
> [...]
> What is the problem here? Should I not call `destroy`? If so,
`destroy()` uses the runtime types informations to detect the
most derived destructor (as you might cast from `TestClass` to
least specialized, i.e `Object`). The type infos for classes
stores the destructor in form of a function pointer that has not
`@nogc` as part of its attributes.
> what should I call instead?
get rid of `destroy()` and instead use your own allocator,
virtual constructor (instead of `this(){}`) and virtual
destructor (instead of `~this(){}`) in a base class.
e.g
```d
class Base
{
static auto make(T : Base, Args...)(Args args)
{
auto size = __traits(classInstanceSize, T);
auto memory = malloc(size)[0..size];
T t = emplace!(T)(memory);
t.construct(args); // call the most derived
return t;
}
void construct() @nogc
{
printf("Base constructor called\n");
}
void destruct() @nogc
{
printf("Base destructor called\n");
free(cast(void*) this);
}
}
class Derived : Base
{
override void construct() @nogc
{
super.construct(); // construct from base to most derived
printf("Derived constructor called\n");
}
override void destruct() @nogc
{
printf("Derived destructor called\n");
super.destruct(); // destruct from derived to base
// finishing with the deallocation
}
}
void main(string[] args) @nogc
{
Base b = Base.make!(Derived);
b.destruct();
}
```
things get called correctly
> Base constructor called
Derived constructor called
Derived destructor called
Base destructor called
That bypasses the runtime mechanism for classes construction and
destruction.
But `new` and `destroy` must not be called anymore, you must get
stick with your own system.
More information about the Digitalmars-d-learn
mailing list