This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: New C++ Attribute: final


On Sun, 29 Feb 2004, Phil Edwards wrote:

> On Sat, Feb 28, 2004 at 09:43:19PM -0500, Kevin Atkinson wrote:
> >   b->f(); // non virtual call since the function in type B is marked
> >           // as final
> >   b->B::f(); // equalvent to the above
> 
> So, what's the benefit?  If that user wants a non-virtual call, he can
> specify the latter, and it will be more portable and obvious to anyone
> reading the code.

Well because the user has to remember to use B::f() instead of f() every 
time.  If a virtual method is "final" either by relaying on the user to 
not override it (by putting a comment in the header file) or forced by the 
compiler (with __attribute__((final)) or just "final" in have) than infact 
b->f() and b->B::f() will have the exact same effect except that the 
latter is more effect since it is a direct function call and not a virtual 
one.  Thus the __attribute__((final)) is essentially an optimization hint.

Here is another example:

Suppose we start off with a simple class

class X {
  int id() const {return id_;}
private:
  int id_;
};

void find(X * x, int id) {
  while (*x && x->id() != id) ++x;
}

Now find is efficient because it assumes x->id() is inline.

Now suppose we decide that we want X to implement an interface:

class Id {
  virtual int id() const = 0;
};

class X : public Id ...

Now find suddenly become rather inefficient because the compiler can no 
longer inline x->id() since it can't be sure that there is not another 
class derived from X that overrides id(), even through the programmer 
knows this.  One solution is to change the code for find:

void find(X * x, int id) {
  while (*x && x->X::id() != id) ++x;
}

So, not such a big deal.  Now suppose there is a LOT of code that makes 
this assumption.  That ALL the code will need to be changed.

Alternatively X can be defined as:

class X {
  __attribute__((final)) int id() const {return id_;}
private:
  int id_;
};

Now the old version of find (ie the one without x->X::id()) is just as 
efficient as it was before.

This example is slightly contrived but it is based on a real situation in 
my own code.

-- 
http://kevin.atkinson.dhs.org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]