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.