🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: an optimization I claim is illegal

#2691
From: Fergus Henderson
Date: Wed, 22 Nov 1995 04:48
81 lines
3449 bytes
Dick Menninger <Dick.Menninger@daytonoh.attgis.com> writes:

>> ==========Somebody said, 11/20/95==========
> 
>> What is meant by the SAME TYPE in the piece of the Draft quoted ? 
>> Would the following code be legal:

No, the code has undefined behaviour.
The types `D1' and `D2' are not the same.
(The code also has undefined behaviour for other reasons - see below.)

>   struct Base
>   {
>       ...
>       virtual void f () { cout << "Base" << endl; };
>   };
>   
>   struct D1 : public Base ...
>   struct D2 : public Base ...
>   
>   void D1::f () { cout << "D1" << endl; new (this) D2 (); }
>   void D2::f () { cout << "D2" << endl; new (this) D1 (); }
>   
>   int main (void)
>   {
>       D1 d1 (7);
>       Base *pb = &d1;
>       for (int i = 0; i < 5; i++)
>           pb->f();
>        return 0;
>   }
>> 
>> The output on g++ is 'D1 D2 D1 D2 D1'. The type as seen by the loop
>> in main does not change, the layout of the types D1 and D2 are the
>> same, they have the same parents and the same function. Why would it
>> be illegal in this case ?  I do not ask this for purely theoretical
>> reason: I do use this (in a somewhat more involved ways) in a design
>> of networked pointers.
>
>Wow.  This code raises several questions.  As coded,
>the "object" goes through several ctors as it changes
>"personality" without ever a dtor called. Is that legal?

Yes, you are allowed to construct a new object over the top
of an existing object without first calling the destructor
for that existing object.

>Is that reasonable? 

A more difficult question.  I certainly wouldn't recommend
that sort of coding style in any but extraordinary circumstances.

>Is there any requirement that the actual underlying
>images be the same size?

No, I'm pretty sure there isn't.  So therefore the above code has
undefined behaviour - it attempts to construct an object of type `D2'
using the storage for a `D1', and there is no guarantee that this
storage will be large enough or correctly aligned.

If you changed the line

       D1 d1 (7);

to

	D1 &d1 = *(D1 *) malloc(sizeof(D1) + sizeof(D2));
	new (&d1) D1 (7);

then the storage would be definitely large enough to hold either
a D1 or a D2 and would be correctly aligned to hold any object,
so this problem wouldn't arise.  But the code would still be undefined
behaviour by 3.8/7, since D1 and D2 are not the same type.

--
Fergus Henderson             	WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au              	PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID: <9532614.29353@mulga.cs.mu.OZ.AU>
Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back
References: <Pine.A32.3.91.951120093534.26414A-100000@zorglub.cae.ca> <DIF0Hw.FrE@falcon.daytonoh.attgis.com>

Show Full Headers
Complete Article Headers
Approved: fjh@cs.mu.oz.au
Date: 22 Nov 95 04:48:58 GMT
From: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Message-ID: <9532614.29353@mulga.cs.mu.OZ.AU>
Newsgroups: comp.std.c++
Organization: Computer Science, University of Melbourne, Australia
Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back
References: <Pine.A32.3.91.951120093534.26414A-100000@zorglub.cae.ca> <DIF0Hw.FrE@falcon.daytonoh.attgis.com>
Subject: Re: an optimization I claim is illegal
X-Original-Date: Wed, 22 Nov 1995 03:46:40 GMT
X-Auth: PGPMoose V1.1 PGP comp.std.c++
 iQBFAgUBMLKr0OEDnX0m9pzZAQHrcgF9GkBTd1OeEGFkip+eP2GWml1U4GSyeHdO
 FNePvT4hobhfJo8uNwakdstlapiQ9vjq
 =cyOX