DIP 1008 Preliminary Review Round 1

Stanislav Blinov via Digitalmars-d digitalmars-d at puremagic.com
Fri May 19 14:51:52 PDT 2017


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- at 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.


More information about the Digitalmars-d mailing list