Article View: comp.std.c++
Article #2691Re: an optimization I claim is illegal
From: Fergus Henderson
Date: Wed, 22 Nov 1995 04:48
Date: Wed, 22 Nov 1995 04:48
81 lines
3449 bytes
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-backReferences:
<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