From: Andy Venikov on
Goran Pusic wrote:
>>
>> That puts an unduly difficult requirement on (presumably custom)
>> operator delete to figure out where the memory came from. And no, it's
>> not always possible to embed that information with the returned memory.
>
> Ahhh, but if you allocate instances of your class both from standard
> heap and your own allocator, are these still the same class? If
> nothing else, they are not the same WRT that particular detail that is
> heap handling.

Well, I don't want my types to be aware of actual physical memory
placement. The same type can be allocated on the heap or anywhere else
and that doesn't change the type's type.

>
> If that is the case, you could have variants of your class: base (with
> actual functionality), one where you use default allocation and one
> that comes from a pool. Then you pass reference to base around for
> work, and call operator delete (compiler picks correct one for you)
> when it's time to go.
That would add virtual dispatch to classes that whouldn't need it otherwise.

>
> You should note that operator new and delete must "reverse-match" ;-)
> in functionality for a given class instance. Even if what you want to
> do was possible, you would still have to keep track of how a
> particular instance was instantiated so that you can call appropriate
> delete version. And if that is so, you could just as well split your
> instances in two actual classes and be done with it. In other words,
> it seems that you don't gain much (if anything) with your idea.

Hmmm, knowledge of what argument to use when calling delete can be
gained statically, without the need to revert to virtual dispatch.

>
> Goran.
>
>

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andy Venikov on
restor wrote:
>> What's the rational for not having placement delete?
>
> C++ has a placement delete it is just spelled differently: I believe
> explicit destructor call. Consider an example:
>
> void createAndDestroy( Class * obj )
> {
> new (obj) Class("obj1"); // ctor w/o allocation
> obj->~Class(); // dtor w/o deallocation
> }
>
> I think the naming convention is confusing, as this question reoccurs
> time and again. And it is the "placement new" that is confusing, as it
> implies special (trivial) form of allocation. They probably should be
> called "explicit constructor call" and "explicit destructor call".
>
> Regards,
> &rzej
>

I believe you've misunderstood my point.

I was talking about a general form of placement new, the one that takes
any user-defined type, not just a pointer to void. You assumed that I
was talking about a version of placement new that was taking a pointer
to void. According to the standard it is not even possible to overload
this function and yes, all it does is calls a constructor in the
specified memory.

Andy.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
Ulrich Eckhardt wrote:
> Andy Venikov wrote:
>> What's the rational for not having placement delete?
>>
>> I know you can define your own placement operator delete, but it will
>> only be called in case a constructor throws an exception when placement
>> new is called. You can't call placement delete directly.
>>
>> This limitation greatly impairs the use of custom allocators.
>
> Wait: Placement new only constructs the object, it doesn't do any
> allocation. Where the memory for the object came from is basically
> irrelevant there. In that light, I'm also not really sure I understand
> your problem and whether the advise below is really relevant to it.

Except that with the complete ineptitude in naming in this part of C++,
placement new is normally taken to refer to any version of operator new
that takes parameters not just the one where you provide the memory
directly.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andy Venikov on
Francis Glassborow wrote:
> Andy Venikov wrote:
>> What's the rational for not having placement delete?
>>
>> I know you can define your own placement operator delete, but it will
>> only be called in case a constructor throws an exception when placement
>> new is called. You can't call placement delete directly.
>>
>> This limitation greatly impairs the use of custom allocators.
>>
>> For example, if you want you allocations to come from a specific memory
>> region and you have a handle to that region you can: (assuming
>> regionAllocator is an object of a custom RegionAllocator class)
>>
>> X * px = new (regionAllocator) X;
>>
>>
>> But you can't
>>
>> delete (regionAllocator) px;
>>
>> you can only
>>
>> delete px;
>
> bu you can also write
> px -> ~X();
>
> Which is really the reason that placement delete is restricted to
> dealing with cases where a ctor throws. It was introduced exactly
> because there was a problem in that case (the compiler has to know what
> the user wants to do if construction as a result of a class member
> placement new fails by throwing an exception.
>
>>
>>
>> That puts an unduly difficult requirement on (presumably custom)
>> operator delete to figure out where the memory came from. And no, it's
>> not always possible to embed that information with the returned memory.
>
> No. You just call the dtor explicitly and then, if necessary (though it
> usually isn't) call an appropriate over;load of operator delete
> explicitly. IOWs decouple destruction from memory management.
>

Sorry, it looks like there's some confusion with terminology.
What I was talking about is operator new that takes any user-defined
type (and any number of them). I believe it is called a placement-new
operator, with the version that takes void * being just a special case
of it.

Some people call it "a new with parameters".

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: peter koch larsen on
On 4 Dec., 19:56, Andy Venikov <swojchelo...(a)gmail.com> wrote:
> Goran Pusic wrote:
>
[snip]
> > You should note that operator new and delete must "reverse-match" ;-)
> > in functionality for a given class instance. Even if what you want to
> > do was possible, you would still have to keep track of how a
> > particular instance was instantiated so that you can call appropriate
> > delete version. And if that is so, you could just as well split your
> > instances in two actual classes and be done with it. In other words,
> > it seems that you don't gain much (if anything) with your idea.
>
> Hmmm, knowledge of what argument to use when calling delete can be
> gained statically, without the need to revert to virtual dispatch.
>
No it can't, and that is the problem. Even in the case of whole
program analysis (and this often is practically not possible) you
could have cases such is:

void f(volatile bool b)
{
int* val = b ? new int(1): new(myallocator) int(2);
...

// how to delete here?
}

/Peter

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]