Newsgroups: comp.lang.dylan,comp.lang.misc,comp.lang.lisp,comp.object,comp.arch
Path: cantaloupe.srv.cs.cmu.edu!europa.chnt.gtegsc.com!gatech!howland.reston.ans.net!xlink.net!slsv6bt!news
From: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Subject: Re: allocator and GC locality (was Re: cost of malloc)
In-Reply-To: hbaker@netcom.com's message of Thu, 10 Aug 1995 21:22:19 GMT
Message-ID: <KANZE.95Aug17152014@slsvhdt.lts.sel.alcatel.de>
Lines: 132
Sender: news@lts.sel.alcatel.de
Organization: SEL
References: <9507261647.AA14556@aruba.apple.com> <3v8g7l$cge@jive.cs.utexas.edu>
	<3vac07$ptf@info.epfl.ch> <3vb382$dtr@jive.cs.utexas.edu>
	<3vbl70$bht@fido.asd.sgi.com> <hbaker-3107951026250001@192.0.2.1>
	<justin-0108951458440001@158.234.26.212> <hbake
	<jyuynr@bmtech.demon.co.uk> <hbaker-0208950816000001@192.0.2.1>
	<jyvgwh@bmtech.demon.co.uk> <3vr85r$758@fido.asd.sgi.com>
	<KANZE.95Aug9150054@slsvhdt.lts.sel.alcatel.de>
	<hbaker-0908950821150001@192.0.2.1>
	<KANZE.95Aug10172327@slsvhdt.lts.sel.alcatel.d
	<hbaker-1008951322190001@192.0.2.1>
Date: 17 Aug 1995 13:20:13 GMT
Xref: glinda.oz.cs.cmu.edu comp.lang.dylan:5084 comp.lang.misc:22726 comp.lang.lisp:18805 comp.object:36953 comp.arch:60497

In article <hbaker-1008951322190001@192.0.2.1> hbaker@netcom.com
(Henry Baker) writes:

|> Newsgroups: comp.lang.dylan,comp.lang.misc,comp.lang.lisp,comp.object,comp.arch
|> From: hbaker@netcom.com (Henry Baker)
|> Organization: nil organization
|> Date: Thu, 10 Aug 1995 21:22:19 GMT

|> In article <KANZE.95Aug10172327@slsvhdt.lts.sel.alcatel.de>,
|> kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) wrote:

|> > In article <hbaker-0908950821150001@192.0.2.1> hbaker@netcom.com
|> > (Henry Baker) writes:
|> > 
|> > |> In article <KANZE.95Aug9150054@slsvhdt.lts.sel.alcatel.de>,
|> > |> kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) wrote:
|> > 
|> > |> > Interestingly enough, there is a legal (and safe) way of implementing
|> > |> > this same idiom in C++.  It's so ugly, though, that I'm not going to
|> > |> > post it.  (I know, if you were worried about ugliness, you wouldn't be
|> > |> > using C++ anyway:-).)
|> > 
|> > |> Go ahead & post it!  Hit us with your ugly stick!  We're adults, and
|> > |> we've turned off the V-chip...
|> > 
|> > Just the essentials (and ignoring eventual reference counting):

Note the name of the class.  This is an implementation class, only to
be used by an interface class (string) that the client sees.  (Also,
its only purpose is to show that the ``ugly struct hack'' can actually
be written in C++.)

|> >     class StringImpl
|> >     {
|> >     public :
|> >         static StringImpl*  mkStringImpl( int length ) ;
|> >         char*               buffer() ;

|> // Gain access to the actual string buffer.

|> >         void*               operator new( size_t s , int length ) ;

|> // Overlard misplacement 'new'.

|> >         void                operator delete( void* ) ;
|> >     private :
|> >                             StringImpl( int length ) ;

|> // private ctor means no static and/or stack instances; being 'private' means
|> // that derived classes can't create any, either.  No default ctor means no
|> // arrays or members.  No friends declared.  _Do_ have default assignment,
|> // so it isn't as safe as you might think.

Correct.  I should have declared a private copy constructor and
assignment operator.

|> >         int                 theLength ;
|> >     } ;
|> > 
|> >     StringImpl*
|> >     StringImpl::mkStringImpl( int length )
|> >     {
|> >         return new( length ) StringImpl( length ) ;
|> >     }
|> > 
|> >     char*
|> >     StringImpl::buffer()
|> >     {
|> >         return (char*)( this + 1 ) ;

|> // This may not work so well for arrays of doubles due to alignment problems.

Quite correct.  In practice, I don't know of an architecture on which
it would fail, but this is actually just a coincidence: the size of
the two int's in the data correspond to (a multiple of) the size of a
double.

|> >     }
|> > 
|> >     void*
|> >     StringImpl::operator new( size_t s , int length )
|> >     {
|> >         assert( s == sizeof( StringImpl ) ) ;
|> >         return ::operator new( s + length ) ;
|> >     }
|> >     void
|> >     StringImpl::operator delete( void* p )
|> >     {
|> >         ::operator delete( p ) ;
|> >     }
|> > 
|> >     StringImpl::StringImpl( int length )
|> >         :   theLength( length )
|> >     {
|> >     }
|> > 
|> > The purpose of the private constructor (and the static mkStringImpl)
|> > is to ensure that 1) all elements *are* created on the heap, and 2)
|> > the extra parameter to new and the parameter to the constructor are
|> > identical.  (Safety, in sum.)
|> > 
|> > In my tests, all of the functions were made inline.

|> You're right, it's ugly.  It's also no safer than something using explicit
|> casting.

Yes and no.  The only advantage I can see in it is that it
encapsulates the ugliness in one small class, rather than spreading it
out throughout the application.  On the other hand, I don't use it in
my string class.

|> For some strange reason :-), it _is_ efficient (at least this part,
|> w/o reference counting), since all of this stuff can be inlined.  The mere fact
|> that compiler writers have been so accomodating in this kind of thing is proof
|> positive that people have to do this kind of end-run around the type system
|> a lot.  (Or at least people at ATT have to do this a lot!)

|> But I think that most people would agree that you've subverted the C++ type
|> system to achieve your end, so 'legal' here would mean a language lawyer's
|> 'legal', rather than 'ethical'.

I agree totally here, which is why I didn't post it to begin with.  I
don't use it; I thought it up more as a response to a challenge, than
as something I would actually want to use.  I certainly don't
recommend programming this way.
-- 
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung


