On Friday, 19 May 2017 at 21:24:51 UTC, Adam D. Ruppe wrote:

"NewExpressions are used to allocate memory on the garbage collected heap (default) or using a class or struct specific allocator. "

"If a NewExpression is used as an initializer for a function local variable with scope storage class, and the ArgumentList to new is empty, then the instance is allocated on the stack rather than the heap or using the class specific allocator. "

IMHO, this has to go. Having alignment control now, and with DIP1000 solving reference escaping, there's absolutely no need in this special syntax; stack-allocated classes are possible as library types.

But it may be beneficial to reconsider the 'new (AllocatorOpts)' syntax, with more thought on interaction with the type system. As in, it's not necessary to have type-specific allocation functions. But some sort of type system flag is required if we want to make the language aware of our allocation schemes. To expand on my previous reply, something like this comes to mind:

// Delcaring class/struct not supporting being allocated by a non-@nogc allocator:
class [(nogc)] ClassName [(template parameters)] { ... }
struct [(nogc)] StructName [(template parameters)] { ... }

// Declaring arrays:
T[][(nogc)] arr;

So it could look like this:

class Allocator
{
    void[] allocate(size_t, TypeInfo ti = null) @nogc { ... }
    void deallocate(void[]) @nogc { ... }
}

Allocator myAllocator = /* however is desired */;

class (nogc) MyClass
{
    int[] gcArray;
    int[] (nogc) nonGCArray;

    // note the ctor itself is not @nogc, since it allocates
    // gcArray, so interoperability is possible
    this()
    {
        gcArray = [1, 2]; // fine
        nonGCArray = [1, 2]; // error
        nonGCArray = new (myAllocator) int[2];
    }

    ~this()
    {
        myAllocator.dispose(nonGCArray);
    }
}

auto a = new MyClass; // error, no allocator provided, GC assumed, MyClass cannot be allocated by GC

auto b = new (myAllocator) MyClass; // fine
auto c = new (theAllocator) MyClass; // error, theAllocator is not @nogc

---

Not a very pretty syntax, but I can't think of a way of making it any prettier...

Bringing this back to exceptions, it should "just work":

class (nogc) NoGCException : Exception { ... }

throw new (myAllocator) Exception("Argh!");

//...

catch (NoGCException e) {
} // error, e is not rethrown or disposed

catch (NoGCException e) {
    myAllocator.dispose(e);
} // fine, e was disposed


This, however, means teaching the language a few extra library constructs. And of course, there's the danger of deallocating with the wrong allocator, but being careful comes with the territory as far as memory management is concerned.

Reply via email to