From 2720186784930731300
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,1ac63fff730e7d59
X-Google-Attributes: gidf78e5,public
From: Salters <salters@lucent.com>
Subject: Re: C++ Memory Allocation Bashing
Date: 1999/08/19
Message-ID: <37BBB3FB.D69D31E2@lucent.com>#1/1
X-Deja-AN: 514751372
X-NNTP-Posting-Host: hvss296.nl.lucent.com
Content-Transfer-Encoding: 7bit
Approved: stephen.clamage@sun.com (comp.std.c++)
References: <37b445e8.82613572@news.airmail.net> <user-1308991347430001@as1-dialup-03.io.com> <130819991418375734%lisa_lippincott@advisories.com> <37B7CC14.54D1E823@lucent.com> <170819991525097118%lisa_lippincott@advisories.com>
X-UID: 0000000001
X-Status: $$$T
Content-Type: text/plain; charset=us-ascii
Organization: Lucent Technologies, Hilversum
Mime-Version: 1.0
Newsgroups: comp.std.c++
Originator: clamage@taumet


Lisa Lippincott wrote:
> 
> Fed up with the problems involved in writing operators new, I suggested
> that a type storage_for<Foo>, representing uninitialized storage
> suitable for Foo, would ease the difficulties.

> I wrote:
> > There would be implicit conversions from Foo* to storage_for<Foo>*
> > and from Foo& to storage_for<Foo>&; these could be reversed with a
> > static_cast.

> Salters <salters@lucent.com> responded:
> > This would of course break type invariants. In C++, it is possible to
> > get memory with the properties demanded:

> > Foo *foo = new foo;
> > storage_Foo* = (~(*foo),foo);

> Well, yes, the static_casts would break type invariants; that's what
> casting does.  The implicit conversions wouldn't break any invariants,
> since the only invariant of storage_for<Foo> is "you can allocate
> a Foo there using placement new."

Not only do the static_casts break invariants, but the implicit
conversions would do that, too. The invariant broken is that
Foo* may point to memory that no longer is a Foo. What happens
with void f(storage_for<Foo> * arg1)? It could conceivably clobber
arg1 (Imagine what happens if new(arg1) throws). Now, if this is
an implicit conversion we could call f like f(&myFoo), and end up
with a broken myFoo. The invariant established by the constructor
exists until the destructor is called, which is why my solution is
valid. You can't demand that the destuctor is called as part of
the implicit conversion.

> And while you can get suitable unitialized storage by constructing
> and then explicitly destroying an object of type Foo (which I assume
> is what you meant to write), that hardly seems like an efficient way
> to go about it.

Efficient, not really. But it is allowed. Usually, you will operate
on *foo, before recycling the memory. If so, the efficieny is no
concern. The question is here, how much can you change in Foo?
That heavily influences what you should do.

Michiel Salters


[ 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              ]




