Topic: private operator new/delete -- definition required?


Author: Wil Evers <bouncer@dev.null>
Date: 1999/12/07
Raw View
Oliver Kamps <okamps@t-online.de> wrote in article
<822e16$fer$1@news01.btx.dtag.de>...

> Wil Evers schrieb in Nachricht <01bf3b26$b2a46ee0$d03240c3@twwie>...

> > That is what the standard says, but is it always implementable?
> > Consider:

> Do you have a pointer to the corresponding section (I couldn't find
> it)?

I don't have access to the final standard.  In the December 1996 working
paper, the relevant text is in section 3.2 [basic.def.odr].  This section
first describes when a function or object is considered 'used', and then
requires a definition for every function or object that is.

> > // file Base.h
> >
> > struct Base {
> >   virtual ~Base();
> > };
>
> > // file Derived.cc
> >
> > struct Derived : Base {
> private:                 // <----------   private, I guess?

That's the usual idiom, but AFAIK, access control does not affect the
requirement to provide a definition for the deallocation function.

> >   void operator delete(void *, size_t);
> > };

> Your example makes sense to me, but I was trying to make a different
> point: My class was not part of an inheritance hierarchy and did not
> have virtual functions.

In that case, I see no technical reason why a compiler would need a
definition for the deallocation function.

However, I do believe the current situation is blurred, because it seems
there are cases where implementations have no choice but to require a
definition, even though the standard does not.

- Wil

Wil Evers, DOOSYS IT Consultants, Maarssen, Holland
[Wil underscore Evers at doosys dot com]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/30
Raw View
Steve Clamage <stephen.clamage@sun.com> wrote:

> Oliver Kamps wrote:
> >
> > in order to prevent heap allocation of objects of a class, operator new
> > and operator delete can be declared private:

> > Which versions of these operators need to be declared to definitely
> > prevent heap allocate objects of this class (throw/nothrow versions +
> > array versions)?
>
> All of the above.

IMHO only one pair of each of new/delete and new[]/delete[] need to be
declared. Other allocation functions (from base class or global) would
then be hidden from use by 'plain' new-expressions, but...

AFAIK you cannot absolutely prevent heap allocation of any single class,
as it could always be used allocated as:

Sample* p = ::new Sample(...);
::delete p;

The only way to prevent this, is to replace *all* standard
(de-)allocation functions with a version that fails (throwing bad_alloc
or returning 0 as appropriate). This might of course affect more than
just one class....

-- J   rg Barfurth




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Wil Evers" <bouncer@dev.null>
Date: 1999/11/30
Raw View
Steve Clamage <stephen.clamage@sun.com> wrote in article
<3842F44F.4CC1D832@sun.com>...

> Oliver Kamps wrote:
> >
> > in order to prevent heap allocation of objects of a class, operator
> > new and operator delete can be declared private:
> >
> > class Sample
> > {
> > public:
> >    // all sorts of stuff
> > private:
> >    void* operator new(size_t);
> >    void operator delete(void*);
> > };
> >
> > Does the standard require that a definition of operator new and
> > operator delete be provided?
>
> Only if they are invoked, directly or indirectly. If they are invoked
> from a place where they are accessible, presumably you will get a
> link-time failure.

That is what the standard says, but is it always implementable?  Consider:

// file Base.h

struct Base {
 virtual ~Base();
};

// file Derived.cc

struct Derived : Base {
 void operator delete(void *, size_t);
};

// file f.cc

#include "Base.h"

void f(Base *bp)
{
 delete bp; // (**)
}

Although a class-specific deallocation function is a static member, it
effectively behaves like a virtual function: the delete-expression marked
(**) must result in a call to Derived's operator delete() if the run-time
type of *bp is Derived.  That in turn seems to imply that an object of type
Derived must somehow be dynamically associated with its deallocation
function (it must either be in Derived's vtbl or be conditionally called
from some other routine in Derived's vtbl), even if the deallocation
function is never invoked.

I don't see an implementation technique that avoids a linker error when
Derived's operator delete is not defined and there is no f() (or no Derived
is ever passed to f()), but on the other hand, I don't think the standard
requires a definition.

Am I missing something?

- Wil

Wil Evers, DOOSYS IT Consultants, Maarssen, Holland
[Wil underscore Evers at doosys dot com]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Oliver Kamps" <okamps@t-online.de>
Date: 1999/11/30
Raw View
Thanks for your answer.
I tried to find the corresponding chapter in the standard document, but =
couldn't find it...

Would you, by any chance, have a pointer to that?


Steve Clamage schrieb in Nachricht <3842F44F.4CC1D832@sun.com>...
>
>Oliver Kamps wrote:
>>=20
>> in order to prevent heap allocation of objects of a class, operator =
new and operator delete can be declared private:
>>=20
>> class Sample
>> {
>> public:
>>    // all sorts of stuff
>> private:
>>    void* operator new(size_t);
>>    void operator delete(void*);
>> };
>>=20
>> Does the standard require that a definition of operator new and =
operator delete be provided?
>
>Only if they are invoked, directly or indirectly. If they are invoked
>from a place where they are accessible, presumably you will get a
>link-time failure.
>
>>=20
>> Which versions of these operators need to be declared to definitely =
prevent heap allocate objects of this class (throw/nothrow versions + =
array versions)?
>
>All of the above.
>
>--=20
>Steve Clamage, stephen.clamage@sun.com
>
>
>[ comp.std.c++ is moderated.  To submit articles, try just posting with =
]
>[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    =
]
>[              --- Please see the FAQ before posting. ---               =
]
>[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              =
]
>
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Oliver Kamps" <okamps@t-online.de>
Date: 1999/12/01
Raw View

Wil Evers schrieb in Nachricht <01bf3b26$b2a46ee0$d03240c3@twwie>...
>Steve Clamage <stephen.clamage@sun.com> wrote in article
><3842F44F.4CC1D832@sun.com>...
>
[snip]
>That is what the standard says, but is it always implementable?  =
Consider:
Do you have a pointer to the corresponding section (I couldn't find it)?

>
>// file Base.h
>
>struct Base {
> virtual ~Base();
>};
>
>// file Derived.cc
>
>struct Derived : Base {
private:                                                               =
// <----------   private, I guess?
> void operator delete(void *, size_t);
>};
>
>// file f.cc
>
>#include "Base.h"
>
>void f(Base *bp)
>{
> delete bp; // (**)
>}
>

[snip]

>
>Am I missing something?
Your example makes sense to me, but I was trying to make a different =
point:
My class was not part of an inheritance hierarchy and did not have =
virtual functions. The class (in my real code) uses the 'resource =
acquisition is initialization' technique (Stroustrup) to make sure that =
database transactions are comitted or rolled back when the object goes =
out of scope (if they aren't, the transaction is rolled back by the =
destructor and an error message is logged).

For that idea to work, objects of these class need to be stack =
allocated.

Oliver




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Oliver Kamps" <okamps@t-online.de>
Date: 1999/11/29
Raw View
Hi,

in order to prevent heap allocation of objects of a class, operator new =
and operator delete can be declared private:

class Sample
{
public:
   // all sorts of stuff
private:
   void* operator new(size_t);
   void operator delete(void*);
};


Does the standard require that a definition of operator new and operator =
delete be provided?


Which versions of these operators need to be declared to definitely =
prevent heap allocate objects of this class (throw/nothrow versions + =
array versions)?


Thanks

Oliver




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/11/29
Raw View
Oliver Kamps wrote:
>
> in order to prevent heap allocation of objects of a class, operator new and operator delete can be declared private:
>
> class Sample
> {
> public:
>    // all sorts of stuff
> private:
>    void* operator new(size_t);
>    void operator delete(void*);
> };
>
> Does the standard require that a definition of operator new and operator delete be provided?

Only if they are invoked, directly or indirectly. If they are invoked
from a place where they are accessible, presumably you will get a
link-time failure.

>
> Which versions of these operators need to be declared to definitely prevent heap allocate objects of this class (throw/nothrow versions + array versions)?

All of the above.

--
Steve Clamage, stephen.clamage@sun.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]