Topic: What is the sense of placement operator new[] ?


Author: nobody@localhost.ucar.edu (nobody)
Date: Wed, 6 Nov 2002 03:10:56 +0000 (UTC)
Raw View
Garry Lancaster:
>
> Mirek Fidler:
> > > > This example seems to work on this platform, but according to
> > > > the note in in 5.3.4/12 this cannot be relied upon.  Unless
> > > > there is a reliable and portable way to figure out how to size
> > > > the placement buffer, I (like Mirek) don't see how placement
> > > > new[] can be useful.
>
> Hyman Rosen:
> > > How about by reading your compiler's documentation?
>
> Neither of my two main compilers documented this, or
> at least if they did I couldn't find it. It's a minor detail and
> not required to be specified, so I wasn't surprised.

And that is the crux of the problem.

Mirek Fidler:
>[Garry Lancaster:]
> >[Mirek Fidler:]
> > >     Personally, I would vote to remove this error-generator from library.
> > > For any practical reason, it can be replaced by loop of non-array
> > > placement new (to be more specific, we are speaking about
> > > void *operator new(size_t, void *) :)
> >
> > Since it *is* possible to use this function safely, either
> > by calling it directly (as in fine, if pointless, line above)
> > or in a non-portable fashion (as suggested by Hyman Rosen),
> > some people will undoubtedly have done so, which counts
> > against its removal from the language. Maybe deprecation
> > would be acceptable.
>
>     Agree. All I wanted is to point out that there is something wrong with
> standard library void *operator new[](size_t, void *)....

The problem is not so much with the standard library operator with signature

      void* operator new[](std::size_t size, void* ptr) throw();

as it is with the unspecified behaviour of new expressions that involve
arrays.  Once again, here is what 5.3.4 actually says:

12    [Example:
      - new T results in a call of operator new(sizeof(T)),
      - new(2,f) T results in a call of operator new(sizeof(T),2,f),
      - new T[5] results in a call of operator new[](sizeof(T)*5+x), and
      - new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f).
      Here, x and y are non-negative __unspecified__ values representing array
      allocation overhead; the result of the new-expression will be offset
      by this amount from the value returned by operator new[]. This over-
      head may be applied in all array new-expressions, including those
      referencing the library function operator new[](std::size_t, void*)
      and other placement allocation functions.  The amount of overhead
      may vary from one invocation of new to another.  ]

where the double underscores were added for emphasis.

The problem is that a new-expression of the form new(buffer) T[10]
invokes the __non-replaceable__ library operator new above, which
__discards__ its size_t argument and returns the value of its buffer
argument (18.4.1.3).  That's useful only if you've already
pre-allocated the buffer, but you won't know the proper size for it
unless you know x, and "unspecified" means that the implementation
is not obliged to tell you what x is.

A reasonable fix for this would be to change "unspecified" to
"implementation-defined" in 5.3.4/12 and to doctor the wording
of the normative section 5.3.4/10 to reflect this.  This would
make things like new(buffer) T[10] useful, albeit non-portable.

Does that seems reasonable to you, Mirek?  If so, maybe a
defect report would be in order.

nobody

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 6 Nov 2002 18:23:30 +0000 (UTC)
Raw View
nobody@localhost.ucar.edu (nobody) wrote
> I agree.  The problem, of course, is that there is no standard way to
> figure out how much overhead to add to a placement buffer in order to
> safely use the placement form of new[].

The standard doesn't provide any method guaranteed to work. However,
I suspect that on all real implementations, 4*sizeof(void*) should
do the trick.

The amount of space needed is not extremely volatile. The biggest
factor is the algorithm used by the compiler/library; alignment
might be significant as well. Generally you shouldn't see big changes
to this amount unless you port to some new compiler.

Using 4*sizeof(void*), and adding suitable assert() macros to any code
that depends on this, should make your code (not absolutely, but)
reasonably safe.

However -- seeing as how this is a standards newsgroup -- I agree that
the next standard ought to give the programmer some way to get this
value. Perhaps this is an example of a trait that doesn't require a
template?

    char buffer[10*sizeof(T) + std::compiler_traits::max_new_overhead];
    T*t = new(buffer) T[10];

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: cxl@centrum.cz ("Mirek Fidler")
Date: Wed, 6 Nov 2002 18:24:08 +0000 (UTC)
Raw View
> The problem is not so much with the standard library operator with
signature
>
>       void* operator new[](std::size_t size, void* ptr) throw();
>
> as it is with the unspecified behaviour of new expressions that involve
> arrays.  Once again, here is what 5.3.4 actually says:
>
> 12    [Example:
>       - new T results in a call of operator new(sizeof(T)),
>       - new(2,f) T results in a call of operator new(sizeof(T),2,f),
>       - new T[5] results in a call of operator new[](sizeof(T)*5+x), and
>       - new(2,f) T[5] results in a call of operator
new[](sizeof(T)*5+y,2,f).
>       Here, x and y are non-negative __unspecified__ values representing
array
>       allocation overhead; the result of the new-expression will be offset
>       by this amount from the value returned by operator new[]. This over-
>       head may be applied in all array new-expressions, including those
>       referencing the library function operator new[](std::size_t, void*)
>       and other placement allocation functions.  The amount of overhead
>       may vary from one invocation of new to another.  ]
>
> where the double underscores were added for emphasis.
>
> The problem is that a new-expression of the form new(buffer) T[10]
> invokes the __non-replaceable__ library operator new above, which
> __discards__ its size_t argument and returns the value of its buffer
> argument (18.4.1.3).  That's useful only if you've already
> pre-allocated the buffer, but you won't know the proper size for it
> unless you know x, and "unspecified" means that the implementation
> is not obliged to tell you what x is.
>
> A reasonable fix for this would be to change "unspecified" to
> "implementation-defined" in 5.3.4/12 and to doctor the wording
> of the normative section 5.3.4/10 to reflect this.  This would
> make things like new(buffer) T[10] useful, albeit non-portable.
>
> Does that seems reasonable to you, Mirek?  If so, maybe a
> defect report would be in order.

    Well, this is one possible solution.

    OTOH, defining that 'implementation-defined' value is potentially very
tricky (I am speaking here about defining it in implementation). Also there
is no real need for this operator, because in any practical case it can be
safely replaced with loop of non-array 'new', like

    for(char *p = buffer; p < buffer + n * sizeof(T); p += sizeof(T))
        new (p) T;

    This does exactly what 'uninformed programmer' expects from discussed
new[] and it is AFAIK completely legal (as far as buffer is properly
aligned).

    So I would vote for Garry's opinion for deprecation. Before that,
perhaps there should be (as defect report ?) inserted note to description of
operator that there is serious problem with using it :)

Mirek



---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: llewelly.@@xmission.dot.com (llewelly)
Date: Thu, 7 Nov 2002 01:04:34 +0000 (UTC)
Raw View
glancaster@ntlworld.com ("Garry Lancaster") writes:

[snip]
> It is perhaps unfortunate that the term "placement new"
> is frequently thought to refer only to the no-action allocation
> technique discussed here, whereas in fact it encompasses
> the general mechanism for supplying extra arguments to
> operator new functions. This can lead to confusion in related
> discussions.
[snip]

Perhaps the phrase 'additional argument new' should be used describe
the general mechanism for supplying extra argument to operator new
functions, and 'placement new' retained for
no-action-put-this-thing-here allocation. However - the standard uses
'placement new' for the general mechanism ...

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Mirek Fidler" <cxl@centrum.cz>
Date: Sat, 2 Nov 2002 16:45:29 CST
Raw View
Note that I am speaking here about array form

void *operator[](size_t, void *);

I know that placement operators are meant for constructing objects in
preallocated (or static) memory.

But how many memory should be prealocated for placement operator new [] ?
ISO C++ defines it as

sizeof(T) * count + non-negative-integer

As there is AFAIK no defined way how to determine that non-negative-integer
(it is meant to represent memory needed to store number of objects), there
is no defined way how to use this operator. E.g.

char Foo buffer[sizeof(Foo) * 10];

new(buffer) Foo[10];

is clearly invalid and likely to crash with most compilers if Foo has
destructor.

Or there is something I have missed ?

Mirek

P.S.: I have encountred this problem while working on GC system - I wanted
to create array forms of 'gc_new' - but that means you have to determine
number of objects in order to destroy them. It comes out that some form of
library support to determine that 'non-negative' value would be great, best
with ability to read number of objects...



---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Andy Sawyer <andys@evo6.com.NoSpam>
Date: Sat, 2 Nov 2002 17:03:37 CST
Raw View
In article <aq0ed6$iqo$1@news.vol.cz>,
 on Sat,  2 Nov 2002 16:45:29 CST,
 "Mirek Fidler" <cxl@centrum.cz> wrote:

> Note that I am speaking here about array form
>
> void *operator[](size_t, void *);
>
> I know that placement operators are meant for constructing objects in
> preallocated (or static) memory.
>
> But how many memory should be prealocated for placement operator new [] ?
> ISO C++ defines it as
>
> sizeof(T) * count + non-negative-integer
>
> As there is AFAIK no defined way how to determine that non-negative-integer
> (it is meant to represent memory needed to store number of objects), there
> is no defined way how to use this operator. E.g.
>
> char Foo buffer[sizeof(Foo) * 10];
>
> new(buffer) Foo[10];
>
> is clearly invalid and likely to crash with most compilers if Foo has
> destructor.
>
> Or there is something I have missed ?

In the case of objects constructed with placement new[], there is no
need for the implementation to store the number of objects in the
array, since they should not be destroyed with delete[], but via
explict calls to ~T(). (In other words, if you choose to control where
the objects are allocated, you also choose to control how they are
counted).


Regards,
 Andy S.
--
"Light thinks it travels faster than anything but it is wrong. No matter
 how fast light travels it finds the darkness has always got there first,
 and is waiting for it."                  -- Terry Pratchett, Reaper Man

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Mirek Fidler" <cxl@centrum.cz>
Date: Sat, 2 Nov 2002 19:57:31 CST
Raw View
> In the case of objects constructed with placement new[], there is no
> need for the implementation to store the number of objects in the
> array, since they should not be destroyed with delete[], but via
> explict calls to ~T(). (In other words, if you choose to control where
> the objects are allocated, you also choose to control how they are
> counted).

    While this sound reasonable, it is just your opinion not supported by
C++ standard. C++ compiler does not distinguishes between new versions when
determining amount of memory to be allocated. Placement new[] is part of
library, not core language.

    Frankly, this situation seems rather dangerous to me. Most people think
that your opinion is true, but it is (most likely) not. Anybody using
placement operator new[] not only uses undefined behaviour, but most likely
constructs a program that is prone to bizzare crashes.

    E.g. try this

struct Foo {
    int dummy;
    ~Foo() { memset(&dummy, 0, 4); // call function to disallow compiler to
ignore destructor... }
};

void main(int, char **)
{
    char buffer[sizeof(Foo) * 10];
    assert((void *)buffer == (void *)new(buffer) Foo[10]);
}

    On my platform, assert fails. I think that it will fail on any platform.
Also, 4 bytes after buffer get corrupted. Very silent bug, very dangerous.

Mirek



---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: glancaster@ntlworld.com ("Garry Lancaster")
Date: Mon, 4 Nov 2002 17:48:39 +0000 (UTC)
Raw View
Andy Sawyer:
> > In the case of objects constructed with placement new[], there is no
> > need for the implementation to store the number of objects in the
> > array, since they should not be destroyed with delete[], but via
> > explict calls to ~T(). (In other words, if you choose to control where
> > the objects are allocated, you also choose to control how they are
> > counted).

Mirek Fidler:
>     While this sound reasonable, it is just your opinion not
> supported by C++ standard. C++ compiler does not
> distinguishes between new versions when determining
> amount of memory to be allocated.  Placement new[] is
> part of library, not core language.

It is both in fact. The new-placement syntax is discussed in
the core language section 5.3.4 and the standard library
placement forms of operator new are discussed in
the library section 18.4.1.3.

It is perhaps unfortunate that the term "placement new"
is frequently thought to refer only to the no-action allocation
technique discussed here, whereas in fact it encompasses
the general mechanism for supplying extra arguments to
operator new functions. This can lead to confusion in related
discussions.

>     Frankly, this situation seems rather dangerous to me. Most people
think
> that your opinion is true, but it is (most likely) not. Anybody using
> placement operator new[] not only uses undefined behaviour, but most
likely
> constructs a program that is prone to bizzare crashes.
>
>     E.g. try this
>
> struct Foo {
>     int dummy;
>     ~Foo() { memset(&dummy, 0, 4); // call function to disallow compiler
to
> ignore destructor... }
> };

I'm unsure why you are concerned that the destructor
not be ignored. Your code never calls it. Is it because
you don't want Foo to be a POD?

> void main(int, char **)
> {
>     char buffer[sizeof(Foo) * 10];
>     assert((void *)buffer == (void *)new(buffer) Foo[10]);
> }

This is undefined in any case, despite being similar to
an example in the published version of the standard
(subsequently dealt with by a defect report). The alignment
of buffer may not  be suitable for an array of Foos.

The following solves that problem, although it is not exception
safe:

void main(int, char **)
{
    char* buffer = ::operator new(sizeof(Foo) * 10);
    assert((void *)buffer == (void *)new(buffer) Foo[10]);
    // If you want to call dtors, do it here explicitly.
    ::operator delete(buffer);
}

>     On my platform, assert fails. I think that it will fail on any
platform.
> Also, 4 bytes after buffer get corrupted. Very silent bug, very dangerous.

Now the alignment issue is fixed, we can examine this
again. According to 18.4.1.3 the call of placement operator
new should just return ptr. Since Foo is not a POD, each
element in the array is then default initialized and a pointer
to the first array element should be returned.

However, as you pointed out earlier, with the array forms
of operator new, the size_t parameter may be more than
sizeof(Foo) * 10.

5.3.4/12 says:

"the result of the new-expression will be offset by this
amount [the number of extra bytes] from the value returned
by operator new[]."

Now the result of the new-expression is a pointer to the
first byte of the array. Therefore, where the number of
extra bytes is non-zero (which is likely and in any case,
permitted), the end of the array will be past the end of
the buffer allocation, so any access to these bytes within
the constructor, or subsequently, will be to unallocated
memory.

So, I agree with you in as far as this means it is unsafe
to use the library supplied placement array operator new
functions via the new-placement syntax. Calling these
functions directly is safe, but pointless (since they don't
do anything except return their void* argument), and using
the new-placement syntax to call custom array operator
new functions may or may not be safe, depending on the
implementation of these functions.

For what it's worth, both VC++6 and CodeWarrior 5 do fail
the assertion and BCB5 won't even compile the code. But
all these compilers are rather old now and the standard is
the final arbiter of correctness, not the compilers, so this
doesn't guarantee we are right.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nobody@localhost.ucar.edu (nobody)
Date: Mon, 4 Nov 2002 19:51:37 +0000 (UTC)
Raw View
Mirek Fidler wrote:
> [Andy Sawyer wrote:]
> > In the case of objects constructed with placement new[], there is no
> > need for the implementation to store the number of objects in the
> > array, since they should not be destroyed with delete[], but via
> > explict calls to ~T(). (In other words, if you choose to control where
> > the objects are allocated, you also choose to control how they are
> > counted).
>
>     While this sound reasonable, it is just your opinion not supported by
> C++ standard. C++ compiler does not distinguishes between new versions when
> determining amount of memory to be allocated. Placement new[] is part of
> library, not core language.

Indeed, according to 5.3.4/10, the new expression may adjust upward the
first parameter (allocation size) passed to any array allocation function.
Furthermore, it leaves unspecified how much this adjustment will be or
whether it will be the same from one call to the next.  This is made
quite clear in 5.3.4/12:

12    [Example:
      - new T results in a call of operator new(sizeof(T)),
      - new(2,f) T results in a call of operator new(sizeof(T),2,f),
      - new T[5] results in a call of operator new[](sizeof(T)*5+x), and
      - new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f).
      Here, x and y are non-negative unspecified values representing array
      allocation overhead; the result of the new-expression will be offset
      by this amount from the value returned by operator new[]. This over-
      head may be applied in all array new-expressions, including those
      referencing the library function operator new[](std::size_t, void*)
      and other placement allocation functions.  The amount of overhead
      may vary from one invocation of new to another.  ]

Further, it is true that the form of placement new[] with signature

      void* operator new[](std::size_t size, void* ptr) throw();

is part of the standard library, and at that one that cannot be replaced
by a user-defined version (18.4.1.3/1).  Its behaviour is defined in
18.4.1.3/5+6, viz., to return ptr and perform no other action.  Presumably
any user-provided version that has additional trailing parameters has to
provide the same behaviour.

>     Frankly, this situation seems rather dangerous to me. Most people think
> that your opinion is true, but it is (most likely) not. Anybody using
> placement operator new[] not only uses undefined behaviour, but most likely
> constructs a program that is prone to bizzare crashes.

I agree.  The problem, of course, is that there is no standard way to
figure out how much overhead to add to a placement buffer in order to
safely use the placement form of new[].

>     E.g. try this
      [ ... ]
>     On my platform, assert fails. I think that it will fail on any platform.
> Also, 4 bytes after buffer get corrupted. Very silent bug, very dangerous.

Here is another variation on that theme:

#include <stddef.h>
#include <string.h>
#include <stdio.h>

struct Foo {
    int dummy;
    ~Foo() {
         memset(&dummy, 0, sizeof(Foo)); // call function to disallow compiler
                                         // to ignore destructor...
    }
};

void *operator new[] (size_t s, void *p, int) {
     printf("operator new[] (size_t s, void *p, int) called, s = %d\n", s);
     return p; }

int main(int, char **)
{
    char buffer[(sizeof(Foo) * 10) + 4];
    void *p = new(buffer, 0) Foo[10];  // uses replacement version above
    printf("array size = %u, p - buffer = %d\n",
           10*sizeof(Foo), (int)((char *)p - buffer));
}

Under gcc version 3.0 the output is:

operator new[] (size_t s, void *p, int) called, s = 44
array size = 40, p - buffer = 4

This example seems to work on this platform, but according to
the note in in 5.3.4/12 this cannot be relied upon.  Unless
there is a reliable and portable way to figure out how to size
the placement buffer, I (like Mirek) don't see how placement
new[] can be useful.

nobody

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 4 Nov 2002 20:53:37 +0000 (UTC)
Raw View
nobody wrote:

> This example seems to work on this platform, but according to
> the note in in 5.3.4/12 this cannot be relied upon.  Unless
> there is a reliable and portable way to figure out how to size
> the placement buffer, I (like Mirek) don't see how placement
> new[] can be useful.


How about by reading your compiler's documentation?
Unless your compiler is going out of its way to
be useless and adversarial (and then why would
you use it?) sizing the placement buffer is going
to be simple. Usually it's going to be a fixed
extra amount for arrays of objects with destructors,
and 0 otherwise.

If you always reserve an extra 8, or maybe 16, bytes,
I'll bet you'll be safe everywhere. Then just stick
an assert inside the placement new verifying that
you hvae the requested room, and you're done.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: cxl@centrum.cz ("Mirek Fidler")
Date: Mon, 4 Nov 2002 22:23:41 +0000 (UTC)
Raw View
> > This example seems to work on this platform, but according to
> > the note in in 5.3.4/12 this cannot be relied upon.  Unless
> > there is a reliable and portable way to figure out how to size
> > the placement buffer, I (like Mirek) don't see how placement
> > new[] can be useful.
>
>
> How about by reading your compiler's documentation?
> Unless your compiler is going out of its way to
> be useless and adversarial (and then why would
> you use it?) sizing the placement buffer is going
> to be simple. Usually it's going to be a fixed
> extra amount for arrays of objects with destructors,
> and 0 otherwise.
>
> If you always reserve an extra 8, or maybe 16, bytes,
> I'll bet you'll be safe everywhere. Then just stick
> an assert inside the placement new verifying that
> you hvae the requested room, and you're done.

    Yes, you are right. From practical point of view.

    But we are speaking about ISO C++ standard here. It at least strange
that there is library function in ISO C++ that cannot be legally used based
on C++ standard.

    Also, it is rather dangerous that most people think (as was pretty well
demostrated in discussion thread :) it works another way than it really
works.

    Personally, I would vote to remove this error-generator from library.
For any practical reason, it can be replaced by loop of non-array placement
new (to be more specific, we are speaking about void *operator new(size_t,
void *) :)

Mirek



---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: glancaster@ntlworld.com ("Garry Lancaster")
Date: Tue, 5 Nov 2002 21:33:31 +0000 (UTC)
Raw View
Mirek Fidler:
> > > This example seems to work on this platform, but according to
> > > the note in in 5.3.4/12 this cannot be relied upon.  Unless
> > > there is a reliable and portable way to figure out how to size
> > > the placement buffer, I (like Mirek) don't see how placement
> > > new[] can be useful.

Hyman Rosen:
> > How about by reading your compiler's documentation?

Neither of my two main compilers documented this, or
at least if they did I couldn't find it. It's a minor detail and
not required to be specified, so I wasn't surprised.

[snip]

Mirek Fidler:
> It at least strange
> that there is library function in ISO C++ that cannot be legally used
based
> on C++ standard.

I agree this area seems strange, but you overstate the
problem slightly. As I already pointed out, the standard
array placement new operator can be called safely, but
using the placement-new syntax to call it is not portable.

In other words,

a = ::operator new(sizeof(Foo) * 10, buffer);    // Fine, if pointless.
b = new (buffer) Foo[10]; // Problematic.

>     Also, it is rather dangerous that most people think (as was pretty
well
> demostrated in discussion thread :) it works another way than it really
> works.

I can see messages from only four people other than
yourself on this thread. Of them only one seemed to
disagree with the consensus as to how placement-new
works. It may seem surprising, but on this very slender
evidence, most people seem to understand just fine.

>     Personally, I would vote to remove this error-generator from library.
> For any practical reason, it can be replaced by loop of non-array
placement
> new (to be more specific, we are speaking about void *operator new(size_t,
> void *) :)

Since it *is* possible to use this function safely, either
by calling it directly (as in fine, if pointless, line above)
or in a non-portable fashion (as suggested by Hyman Rosen),
some people will undoubtedly have done so, which counts
against its removal from the language. Maybe deprecation
would be acceptable.

Furthermore, *custom* array placement operator new functions
may be used portably both when called directly or when called
via the placement-new syntax, so removing, or even deprecating,
the whole concept of array placement new would definitely be
going too far.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: cxl@centrum.cz ("Mirek Fidler")
Date: Tue, 5 Nov 2002 22:11:42 +0000 (UTC)
Raw View
> >     Also, it is rather dangerous that most people think (as was pretty
> well
> > demostrated in discussion thread :) it works another way than it really
> > works.
>
> I can see messages from only four people other than
> yourself on this thread. Of them only one seemed to
> disagree with the consensus as to how placement-new
> works. It may seem surprising, but on this very slender
> evidence, most people seem to understand just fine.

    Well, when I was not sure I am right, I started another discussion
thread in c++.moderated. At least 3 peoples did not get it right...

> Since it *is* possible to use this function safely, either
> by calling it directly (as in fine, if pointless, line above)
> or in a non-portable fashion (as suggested by Hyman Rosen),
> some people will undoubtedly have done so, which counts
> against its removal from the language. Maybe deprecation
> would be acceptable.

    Agree. All I wanted is to point out that there is something wrong with
standard library void *operator new[](size_t, void *)....

> Furthermore, *custom* array placement operator new functions
> may be used portably both when called directly or when called
> via the placement-new syntax, so removing, or even deprecating,
> the whole concept of array placement new would definitely be
> going too far.

    Sure. I would never propose removing placement (or rather call it 'new
with more arguments' :) new syntax. It is certainly important.

Mirek


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]