Article View: comp.std.c++
Article #2616Re: an optimization I claim is illegal
From: Tim Hollebeek
Date: Fri, 17 Nov 1995 19:17
Date: Fri, 17 Nov 1995 19:17
106 lines
3758 bytes
3758 bytes
In article <martelli.816557310@cadlab>,
Alex Martelli <martelli@cadlab.it> wrote:
>
>In a debate over on comp.compilers, there was some discussion of
>whether it would be legal for a compiler to optimize the following
>snippet of code...:
>
>class P {
>public: virtual void f();
> // etc
>};
>
>// with a P* p
> for(i=0;i<1000;i++)
> p->f();
>
>by hoisting out of the loop the virtual lookup for f()'s address.
I'll admit it, I was the one who got this entire debate started :-)
I originally posted to comp.compilers because I was convinced of the
legality, but wondering about the feasibility and whether real
compilers actually did this yet. comp.std.c++ is probably a better
forum to debate the legality of the optimization.
>Here's the counterexample I have in mind:
>
>#include <iostream>
>
>class Base {
>public: virtual void f() {cout<<"Base ";}
>};
>class Derived: public Base {
> int countdown;
>public: Derived(int n=2):countdown(n) {}
> virtual void f();
>};
>int main()
>{
> Base *p=new Derived;
> for(int i=0;i<4;i++)
> p->f();
> cout<<endl;
> return 0;
>}
>
>and, separately compiled perhaps,
>
>#include <iostream>
>#include <new>
>// above-seen declarations of Base and Derived, then:
> virtual void Derived::f() {
> cout<<"Derived ";
> if(--n==0) {
> this->~Derived();
> new(this) Base;
> }
> }
>
>Isn't this a strictly conformant, well-defined program ...
I think it's pretty clear the answer is no:
[class.dtor] #11:
"... Once a destructor is invoked for an object, the object no longer
exists; ..."
Now, it is legal to use a (T*) as a (void*) even after the T's life
has ended, however:
[basic.life] #7:
"If, after the lifetime of an object has ended and while the storage
which the object occupied still exists, a new object is created at the
storage location which the original object occupied, a pointer that
pointed to the original object will automatically refer to the new
object and, once the lifetime of the new object has started, can be
used to manipulate the new object, if:
[...]
... the new object is of THE SAME TYPE as the original object ...
[...]
The conditions are not met, so the pointer 'p' DOES NOT refer to the
new object you have created. It still refers to the old object whose
life has ended, and hence it can only be used in very restricted ways.
Specifically, dereferencing it or using it as on object of type T
invokes undefined behavior.
So you program is not strictly conforming. Based on the careful
wording of [basic.life], it does indeed seem that the comittee was
very careful to make sure the type of an object cannot be changed
arbitrarily.
-Tim
--
Tim Hollebeek | Everything above is a true statement, for sufficiently
PChem Grad Student | false values of true.
Princeton Univ. | C++ == OOP--
-------------------| tim@handel.princeton.edu http://wagner.princeton.edu/~tim
[ 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:
<48iks8$6mn@cnn.Princeton.EDU>Path:
arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamageReferences:
<martelli.816557310@cadlab>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage From: tim@franck.Princeton.EDU (Tim Hollebeek) Newsgroups: comp.std.c++ Subject: Re: an optimization I claim is illegal Date: 17 Nov 1995 19:17:21 GMT Organization: Princeton University Approved: clamage@eng.sun.com (comp.std.c++) Message-ID: <48iks8$6mn@cnn.Princeton.EDU> References: <martelli.816557310@cadlab> NNTP-Posting-Host: taumet.eng.sun.com Content-Type: text X-Nntp-Posting-Host: franck.princeton.edu Content-Length: 2901 X-Lines: 102 Originator: clamage@taumet