Hello,

I was having a look at the new nogc annotation and therefore wrote some code that creates an instance on the heap bypassing the GC (code adapted from http://dpaste.dzfl.pl/2377217c7870). Problem is that calls to call the class' constructor, destructor and others can't be called anymore once nogc is used. So the question is how to get manual allocation and deallocation done with using nogc. Here is the experimental code:

@nogc
T nogcNew(T, Args...) (Args args)
{
    import std.conv : emplace;
    import core.stdc.stdlib : malloc;

    // get class size of class object in bytes
    auto size = __traits(classInstanceSize, T);

    // allocate memory for the object
    auto memory = malloc(size)[0..size];
    if(!memory)
    {
        import core.exception : onOutOfMemoryError;
        onOutOfMemoryError();
    }

    // call T's constructor and emplace instance on
    // newly allocated memory
    return emplace!(T, Args)(memory, args);
}

@nogc
void nogcDel(T)(T obj)
{
    import core.stdc.stdlib : free;

    // calls obj's destructor
    destroy(obj);

    // free memory occupied by object
    free(cast(void*)obj);
}

@nogc
void main()
{
        TestClass test = nogcNew!TestClass();
        test.x = 123;
        nogcDel(test);
        test.x = 456;   // no protection violation ?!

        // remove @nogc to run this
        TestClass t = new TestClass();
        t.x = 789;
        delete t;
        t.x = 678;      // protection violation as expected
}

I have omitted the code for the TestClass class to save space. Problem is that the compiler outputs this:

Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' cannot call non-@nogc function 'core.exception.onOutOfMemoryError' Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' cannot call non-@nogc function 'std.conv.emplace!(TestClass, ).emplace' Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' cannot call non-@nogc function 'object.destroy!(TestClass).destroy'

Is there a way to get around this? Then the test.x = 456; did not cause a protection violation although the instance was deallocated before calling nogcDel. Something with the deallocation in nogcDel seems not to work. Some hint appreciated on this. When calling delete t the protection violation happens on the next line as expected.

Thanks a lot, Bienlein

Reply via email to