🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #457

Asymmetry: "new (placement) T" vs. "Tptr->~T"

#457
From: Jens M. Dill
Date: Wed, 29 Aug 1990 20:37
61 lines
3677 bytes
Is anyone else bothered by the inherent asymmetry in the application of
constructors and destructors to an object that is to reside in a known
memory location?  To take a known area of memory and intitialize it as an
object of type T, one is supposed to use the "placement" form of the "new"
operator, which implicitly invokes any necessary constructor:

            T* Tptr = new (KnownArea) T ;

To undo this, one is supposed to apply the destructor ~T explicitly:

            Tptr->~T () ;

This is all very well if one knows whether or not T is a class with a
destructor, but consider the case where T is a type argument to a template
(or to a macro that emulates the template facility).  In this case, one
cannot know if T is a type with constructors or destructors, since that
information is unavailable until T is bound in a template-class definition.

This causes no problems with the constructor invocation, since the constructor
is invoked implicitly by operator new, which can be applied to objects of any
type, whether or not they have constructors.  The problem comes with ensuring
that the destructor is properly invoked.  Here, one must invoke the destructor
explicitly, since operator delete may not be applied to memory not allocated
by operator new.  But one may not invoke the destructor explictly if no
destructor id defined.  And one has no way of telling, for a template type-
argument T, whether or not T has a destructor.

Possible fixes:

1.  Define a version of the delete operator that accepts an indicator telling
    it that the memory is not to be returned to the heap, as it was allocated
    by some other mechanism.  This is the most symmetric and general solution,
    but I can think of no good syntax for it, and it perpetuates a problem
    introduced by the "new" placement syntax:  namely, that "new" and "delete"
    are being invoked for their side effects only (constructor/destructor
    invocation) rather than for their intended purpose (heap allocation/
    deallocation).

2.  Make it legal to explicitly invoke a destructor for any type T, whether
    or not it has one.  Invocations of the form "Tptr->~T" where T is a
    primitive type or the name of a class without a destructor would do
    nothing.  This solves the problem, even though it retains the asymmetry.

3.  Other variants, etc.  I do not see an obious best choice here.


For those who are interested, the problem arose when defining a stack
template that allocates space in multi-element frames.  Rather than
initializing all elements of the stack frame at the time the frame was
allocated (which would be relatively easy), I wanted to initialize each
element as it receieved a new value (via PUSH) and invoke the destructor
for the corresponding POP.  There is a workaround:  declare yet another
container class that holds just one stack element and defines only the
new and delete operators to have the PUSH and POP semantics.  Perhaps
that workaround is purer C++, even though it introduces a gratuitous
class definition.

*=====* TIME CANNOT BE WASTED *=====*       -- Jens M. Dill
 \ But it can be used for purposes /           jmd@dlogics.com
  \ other than what was intended. /
   *=============================*
Technical Details
Message-ID: <620@dlogics.COM>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!dlogics!jmd

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!dlogics!jmd
From: jmd@dlogics.COM (Jens M. Dill)
Newsgroups: comp.std.c++
Subject: Asymmetry: "new (placement) T"  vs. "Tptr->~T"
Keywords: placement new delete constructor destructor template
Message-ID: <620@dlogics.COM>
Date: 29 Aug 90 20:37:44 GMT
Organization: Datalogics Inc., Chicago
Lines: 61