This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: RFC: New C++ Attribute: final
- From: Kevin Atkinson <kevina at gnu dot org>
- To: Phil Edwards <phil at codesourcery dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 1 Mar 2004 01:18:46 -0500 (EST)
- Subject: 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