Eliminate class allocators and deallocators?

Jeremie Pelletier jeremiep at gmail.com
Thu Oct 8 07:28:38 PDT 2009


Don wrote:
> 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.
> 

Yeah I agree now after reading most of this thread, I know that these 
keywords just map to functions.

I've seen a proposal of a global new template somewhere, I don't like 
that since at the global scope there are also structs, arrays and 
whatnot that can be allocated by 'new'.

I don't like the static new either since it prevents subclasses from 
overriding their new/delete operations.

What would then be a good way to replace new/delete operators to still 
have them overridable? Isn't that the convenience that first got them to 
be used in the first place? Other than global new/delete overrides which 
is plain silly in D.

I've pretty much found alternatives to all my other points against 
taking out new/delete except for the override feature, find me an 
alternative for that too and I'll be voting for new/delete to be runtime 
function instead of language keywords, cause I can't think of anything 
right now.



More information about the Digitalmars-d mailing list