Eliminate class allocators and deallocators?

Don nospam at nospam.com
Thu Oct 8 02:20:34 PDT 2009


Andrei Alexandrescu wrote:
> Jeremie Pelletier wrote:
>> Andrei Alexandrescu wrote:
>>> Hello,
>>>
>>>
>>> D currently allows defining class allocators and deallocators. They 
>>> have a number of problems that make them unsuitable for D 2.0. The 
>>> most obvious issue is that D 2.0 will _not_ conflate destruction with 
>>> deallocation anymore: invoking delete against an object will call 
>>> ~this() against it but will not recycle its memory. In contrast, 
>>> class deallocators are designed around the idea that invoking delete 
>>> calls the destructor and also deallocates memory.
>>>
>>> So I'm thinking of removing at least class deallocators from the 
>>> language. Class allocators may be marginally and occasionally useful 
>>> if the user takes the matter of deallocation in her own hands.
>>>
>>> A much better way to handle custom allocation of classes would be in 
>>> the standard library.
>>>
>>> What do you think?
>>>
>>>
>>> Andrei
>>
>> I wouldn't like delete to go away at all, I use it for all my non-gc 
>> objects like this watered down example:
>>
>> class ManualObject : Object {
>>     new(size_t size) { return malloc(size); }
>>     delete(void* mem) { free(mem); }
>> }
>>
>> And then I can easily subclass it for any objects that doesn't need 
>> the GC. I've got similar constructs for arrays and structs.
> 
> Clearly you use those objects in a very different manner than GC 
> objects. So by using new/delete with them you're fooling yourself.
> 
> // untested
> class ManualObject {
>     static T create(T : ManualObject)() {
>         auto p = malloc(__traits(classInstanceSize, T));
>         memcpy(p, T.classinfo.init.ptr, __traits(classInstanceSize, T));
>         auto result = cast(T) p;
>         result.__ctor();
>         return result;
>     }
>     static void yank(ManualObject obj) {
>         free(cast(void*) obj);
>     }
> }
> 
> Looks like a fair amount of work? At some level it actually should, but 
> we can put that kind of stuff in the standard library.
> 
>> malloc/free are nice, but they don't allow for elegant abstractions 
>> like new/delete does (for example if you want to use a specialized 
>> non-gc allocator you can just replace a few calls instead of every 
>> allocation).
> 
> They do if you're willing to write just a bit of scaffolding.
> 
>> I also use delete when I no longer need large blocks of memory, I 
>> don't want them to just become uninitialized and sitting on the GC. 
>> When I want to do that I just nullify my references.
>>
>> If you're afraid of deleting an object that may still have valid 
>> references, use smart pointers, or don't delete it at all if it sits 
>> on the gc and just call a .destroy() method.
>>
>> Also in my runtime the delete implementations do free the memory, they 
>> don't just call the finalizer.
>>
>> In any ways, just don't remove new/delete overrides from the language 
>> please, just call it a low-level technique or something to scare the 
>> beginners away and let people who want it have it :)
> 
> I strongly believe custom new/delete must go.
> 
> 
> Andrei

Yes. The only reason you want them in C++ is because C++ makes 
constructors magical, by always glueing a memory allocation in front of 
them, and pretending they're not a function.
Then you need to introduce placement new to avoid the memory allocation bit.

Let's call a spade a spade: a constructor is just a function that 
establishes the invariant on a piece of memory which it recieves as a 
parameter. If you stop the pretense, you don't need the language machinery.




More information about the Digitalmars-d mailing list