🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: Correctness of compilers behavior

#3473
From: Fergus Henderson
Date: Sun, 18 Feb 1996 02:14
85 lines
3083 bytes
"Constantine Antonovich:" <const@Orbotech.Co.IL> writes:

>//     Could somebody  tell if the following code is
>// ill-formed

The code is well-formed, but has undefined behaviour.
So you should not be surprised if you get different
results using different compilers.

>#include <iostream.h>
>#include <assert.h>
>#include <new.h>
>
>class A {
>public:
>  A(void)     { cout << "A constructed" << endl; }
>  A(const A&) { cout << "A copied" << endl; }
>  ~A()        { cout << "A destructed" << endl; }
>};
>
>class B {
>public:
>  B(void)     { cout << "B constructed" << endl; }
>  B(const B&) { cout << "B copied" << endl; }
>  ~B()        { cout << "B destructed" << endl; }
>};
>
>A* foo(unsigned size)
>{
>  assert(sizeof(A)==sizeof(B));

This assertion is not guaranteed to succeed.  It would take an
extremely perverse implementation for it to fail, however, so I think it
would be very portable, even though it is not strictly guaranteed to work.

>  B* bptr=new B[size];
>  A* aptr=(A*)bptr;

This cast has unspecified behavior.  (See 5.2.9 [expr.cast.reinterpret]/8.)
However, I would expect it to work on most implementations.

>  for (unsigned i=0; i<size; ++i) {
>    (bptr+i)->~B();

That's fine.

>    new(aptr+i) A;

Assuming that `(void *)(aptr+i)' is correctly aligned and points to an
areas of sufficient space (which as noted above is not guaranteed, but
is likely to hold for most implementations) this is OK.

>  }
>
>  return aptr;
>}
>
>int main(void)
>{
>  A* arr=foo(2);

With the caveats listed above, this is likely to be OK on most implementations.

>  delete [] arr;

This has undefined behaviour.  It contravenes 5.3.5[expr.delete]/2, which
says that the expression passed to `delete []' must be a pointer to the
first element of an array of objects allocated with `new []'; this is not
the case, because although there once was such an array at that memory
location, its lifetime ended when the memory was overwritten by the calls
to placement new (see 3.8[basic.life]/1).

>  return 0;
>}

--
Fergus Henderson             	WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au              	PGP: finger fjh@128.250.37.3

[ To submit articles: Try just posting with your newsreader.  If that fails,
		      use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]
Technical Details
Message-ID: <4g3i93$9lp@mulga.cs.mu.OZ.AU>
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage
References: <3122157A.2EB2@orbotech.co.il>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage
From: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Newsgroups: comp.std.c++
Subject: Re: Correctness of compilers behavior
Date: 18 Feb 1996 02:14:25 GMT
Organization: Comp Sci, University of Melbourne
Approved: clamage@eng.sun.com (comp.std.c++)
Message-ID: <4g3i93$9lp@mulga.cs.mu.OZ.AU>
References: <3122157A.2EB2@orbotech.co.il>
NNTP-Posting-Host: taumet.eng.sun.com
Content-Type: text
X-Nntp-Posting-Host: munta.cs.mu.oz.au
Content-Length: 2150
Originator: clamage@taumet