July 25, 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-@nogc function "object.destroy!(true, TestClass).destroy

import std.stdio : printf;
import core.lifetime : emplace;
import core.stdc.stdlib : malloc, free;

class TestClass {
    int x;

    this(int x) @nogc {
        printf("TestClass's constructor called\n");
        this.x = x;
    }


    ~this() @nogc {
        printf("TestClass's destructor called\n");
    }
}

@nogc void
main() {
    auto size = __traits(classInstanceSize, TestClass);
    auto memory = malloc(size)[0..size];
    TestClass x = emplace!(TestClass)(memory, 1);

    printf("TestClass.x = %d\n", x.x);

    destroy(x);
    free(cast(void*)x);
}

What is the problem here? Should I not call destroy? If so, what should I call instead?

You can call function like destroy with right attributes for class variable if you known exact type of the class (no base class referece or interface):

https://github.com/atilaneves/automem/blob/master/source/automem/utils.d

July 25, 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-@nogc function "object.destroy!(true, TestClass).destroy

import std.stdio : printf;
import core.lifetime : emplace;
import core.stdc.stdlib : malloc, free;

class TestClass {
    int x;

    this(int x) @nogc {
        printf("TestClass's constructor called\n");
        this.x = x;
    }


    ~this() @nogc {
        printf("TestClass's destructor called\n");
    }
}

@nogc void
main() {
    auto size = __traits(classInstanceSize, TestClass);
    auto memory = malloc(size)[0..size];
    TestClass x = emplace!(TestClass)(memory, 1);

    printf("TestClass.x = %d\n", x.x);

    destroy(x);
    free(cast(void*)x);
}

What is the problem here? Should I not call destroy? If so, what should I call instead?

Try using the scope storage class. You will lose the ability to explicitly call the destructor, but maybe it is good enough for your purposes.

The following works:

import std.stdio : printf;
import core.lifetime : emplace;
import core.stdc.stdlib : malloc, free;

    class TestClass {
        int x;

        this(int x) @nogc {
            printf("TestClass's constructor called\n");
            this.x = x;
        }


        ~this() @nogc {
            printf("TestClass's destructor called\n");
        }
    }

    @nogc void
    main() {
        //auto size = __traits(classInstanceSize, TestClass);
        //auto memory = malloc(size)[0..size];
        scope /*notice the scope storage class*/TestClass x =  new TestClass(1);// emplace!(TestClass)(memory, 1);

        printf("TestClass.x = %d\n", x.x);

        //destroy(x);
        //free(cast(void*)x);
    }

If you absolutely want to be able to explicitly call the destructor, then custom functions are the only option, unfortunately.

1 2
Next ›   Last »