🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: an optimization I claim is illegal

#2597
From: Steve Clamage
Date: Thu, 16 Nov 1995 22:49
105 lines
3323 bytes
In article 816557310@cadlab, martelli@cadlab.it (Alex Martelli) writes:
>
>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.

> ...

>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 am not at all convinced that constructing a new object on top of "this"
is well-defined. Recent changes in the DWP assure us that you can
construct a new object of the SAME type on top of an existing object if
you destroy the old one first, but even this case is not discussed in
terms of doing it from inside a member function.

Here is a different example which is well-defined. (I haven't compiled
it, so please excuse any typos.)

class Base { public: virtual void f(); };
class Derived : public Base { public: virtual void f(); };

extern Base* array[4] = { new Base, new Derived, new Base, new Derived };
Base* p = 0;

int main()
{
	p = Base[0];
	for(int i=0; i<4; i++)
		p->f();
}

void X::f() // X is Base or Derived
{
	static int i = 0;
	... do something unique for each class, then
	i = (i+1)%4;
	p = array[i]; // change the value of p
}

The difference here is that p is global, not local, so its value cannot
be assumed to be unchanged. You didn't say whether that was an assumption
in the original case. Similarly, you could make p a local variable, but
pass it by reference to f. Again, it cannot be assumed to be unchanged,
which may not fit the original problem definition.

If we assume that the VALUE of p does not change, the question is whether
the object it points to can change type (except during construction and
destruction). I think the answer is no, in which case the optimization is valid.
---
Steve Clamage, stephen.clamage@eng.sun.com



---
[ 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: <48ge05$h00@engnews1.eng.sun.com>
Path: arc1-ca.pugleaf.net!128.32.155.1!matt
References: <martelli.816557310@cadlab>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!128.32.155.1!matt
From: clamage@Eng.Sun.COM (Steve Clamage)
Newsgroups: comp.std.c++
Subject: Re: an optimization I claim is illegal
Date: 16 Nov 1995 22:49:04 GMT
Organization: Sun Microsystems Inc.
Approved: matt@physics2.Berkeley.EDU (Matt Austern)
Message-ID: <48ge05$h00@engnews1.eng.sun.com>
References: <martelli.816557310@cadlab>
Reply-To: clamage@Eng.Sun.COM
NNTP-Posting-Host: physics2.berkeley.edu