On Wednesday, 2 January 2013 at 18:09:34 UTC, Ali Çehreli wrote:
This issue has come up on the D.learn forum recently. The following program terminates with core.exception.InvalidMemoryOperationError. (Tested with dmd 2.061 and 2.060)

string foo()
{
    return "a";
}

class Foo
{
    ~this()
    {
        auto s = foo() ~ "b";
    }
}

void main()
{
    new Foo;
}

It is obvious that dtor causes GC activity and current GC is not reentrant. If you change dtor to for e.x. ~this() { doSomething(); }, so now it is impossible to make conclusion without doSomething() source.

My guess is that the destructor is being executed at a point where the runtime is not in a state where allocating memory is allowed.

Yes.

Has the programmer made a mistake? What operations are safe in a class destructor? (I think the question is valid for the destructors of GC-owned struct objects as well.)

In general, operations that involve GC inside class dtors that are run after garbage process have been started, lead to InvalidMemoryOperationError exceptions. This means that if you cannot guarantee that class destructors are called before garbage collection, you will have problems.

Since the programmer should not be expected to know the implementations of every function, the only safe action is to not call any function in a destructor at all, as that function may be allocating dynamic memory under certain conditions. I hope I am wrong. :) Can we expect the runtime be cooperative until all finalizers are executed?

Ali

Yes, necessity to restrict operations in class dtors are inconvenient. The solution is to fix the GC.

Reply via email to