Topic: Final keyword in C++
Author: "analizer" <analizer@yandex.ru>
Date: Mon, 26 Jun 2006 09:30:00 CST Raw View
There are already "sealed" keyword introduced in Visual Studio .NET,
i.e. Visual C 8.0 compiler. Propably this keyword is present in VC7.0
too.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Mon, 26 Jun 2006 09:49:04 CST Raw View
"Alf P. Steinbach" wrote:
> * kanze:
> > SuperKoko wrote:
> > [...]
> >> Anyway, I fear that, if 'final' is added to the language,
> >> programmers will abuse of this new keyword (uselessly
> >> reducing extensibility), as they did in Java.
> > Interesting. From what I've seen of Java, just the opposite
> > is the case; most programmers don't bother to declare a
> > function final, even if they're not prepared to handle a
> > different implementation of it.
> > Unless you intentionally design a function to be replaced,
> > it generally cannot be robustly replaced. Almost none of
> > the Java programmers I've known, and very little of the code
> > I've seen, actually considers the issue. Which means that
> > you cannot override most functions and still be sure that
> > the code works, but the functions are not declared final.
> I think the issue is much more complex than that.
I agree that the issue can be very complex, and that knowing
when final is appropriate requires a thorough understanding of
the design issues involved.
> E.g., consider adding tracing of member function calls for
> some pre-existing frozen class. I think the complexity is so
> high that in a discussion of pro and con every argument from
> one side could be countered by an argument from the other
> side, and vice versa, ad nauseam and infinitum, and thus, I
> think that disqualifies the notion of 'final' for member
> functions: when it's that unclear, adding complexity to the
> language is IMO ungood.
When working in Java, I had more than a few cases where we used
it, to good avail. The typical example is where you implement
an abstract base class (an interface in Java), and the
implementation itself uses the template pattern. If the user
overrides any of your functions, you'll be in deep trouble,
since they define the pre- and post-conditions, and ensure the
invariants.
It's interesting to note that my opinion here is based on
concrete experience. I'm not advocating final for classes,
because it has been my experience that programmers (even very
average programmers) don't generally derive from a class that
wasn't designed for derivation. It's simply not a problem. (In
C++. Java needs it for other reasons.) On the other hand, I've
really had problems with programmers overriding the wrong
functions when they derived from a class meant to act as a base
class. We only added final when we started having problems.
This may be related to the organizational structure I was
working in: we had technical experts, like myself, writing the
basic framework, and domain experts (specialists in banking)
writing the layers on top. The domain experts weren't any
better with the technical issues than I was with the domain
issues, and one of the principal goals was precisely to limit
the problems they could encounter---thus, for example, although
the application was multi-threaded, the domain experts never had
to deal with threading issues.
I think that such an organization is not that infrequent; at
least I tend to find myself in one often. And obviously, domain
experts are still expected to read the documentation; if the
documentation of my class says not to override this function, we
expect them not to do so. But nobody's perfect, of course, and
a compiler error when the domain expert compiles is definitly
preferrable to a week long debugging session because your class
invariants don't hold (which causes problems far from the site
of the actual error). Admittedly, most of the time, a five
minute code review is sufficient to find the error, and week
long debugging sessions, while not unheard of, aren't all that
frequent either. So I'm not adament about the issue; the gain
is relatively small. On the other hand, so is the cost (in
terms of added complexity), so why not.
At any rate, the question is moot. There's currently no
proposal before the committe (at least that I know of), I don't
feel motivated enough to write one, even though I'd definitly
endorse one if someone else did the work, and it's really too
late for new proposals anyway. So it's not going to happen.
> As the OP noted there is already an idiom for 'final' for C++
> classes (it's in the FAQ). And the OP's argument is that
> language support could allow optimizations. Well, I think it
> would be an optimization very seldom "activated" for
> well-designed code, and in my humble opinion C++ has enough
> cases of making premature optimization all too easy.
> So I think 'final' for classes is ungood too.
For classes, I agree. I'm not familiar with the idioms which
require derivation, but people who I trust, and who know more
about meta-programming that I do, say they exist. And about the
only motivation for banning derivation that I can think of is to
forbid overriding functions that you don't want to have
overridden, and that's best handled on a function by function
basis anyway. (Again, Java is different. The somewhat strange
interactions between package and protected access mean that
there are cases where you want to forbid derivation for security
reasons. Cases which occur more frequently than they would in
C++ because of the lack of friends---if another class needs
access to your internal data, the only way to grant it is to
make both classes members of the same package, and grant package
access. Which also grants protected access.)
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: wkaras@yahoo.com
Date: Tue, 20 Jun 2006 22:23:25 CST Raw View
Alexei Alexandrov wrote:
> Hi All!
>
> Are there any plans regarding adding the "final" keyword in C++ for specifying leaf classes in inheritance hierarchy? I mean, similar to what they have in Java. I know that there some tricks to achieve this in C++ today, but those tricks don't allow compiler to do any optimizations because the information is implicit. Important optimization that could be achieved is eliminating the cost of virtual call for leaf class pointer:
>
> class IDataManager
> {
> public:
> virtual void doWork() = 0;
> };
>
> final class DataManagerImpl : public IDataManager
> {
> virtual void doWork()
> {
> }
> };
>
> void doSomething(DataManagerImpl *dataMgr)
> {
> // Compiler can perform statically resolved call here because
> // the pointer is to final class and the call cannot be polymorphic
> dataMgr->doWork();
> }
>
> I faced such patterns several times when exposing the interface to external clients, but using the direct implementation pointer internally. I always kinda worry about redundant virtual call in such cases - I understand that it's negligible on modern architectures but still - it might be interesting.
>
> --
> Alexei Alexandrov
What are the advantages of using "final" as opposed to doing this:
class A : public Base
{
.
int final_x(int i);
virtual int x(int i) { return(final_x(i)); }
.
};
and then calling final_x instead of x for instances of A ?
It's clear that it would be desirable for the compiler to
simply generate a single function with the (decorated)
names A::final_x and A::x both tranlating to the start
address of this (single) function.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Ganesh" <sgganesh@gmail.com>
Date: Wed, 21 Jun 2006 09:37:49 CST Raw View
"Gene Bushuyev" wrote:
> "Alexei Alexandrov" <alexei.alexandrov@gmail.com> wrote in message
> news:4fi5jeF1jji1nU1@individual.net...
> > Hi All!
> >
> > Are there any plans regarding adding the "final" keyword in C++ for specifying
> > leaf classes in inheritance hierarchy? I mean, similar to what they have in
> > Java. I know that there some tricks to achieve this in C++ today, but those
> > tricks don't allow compiler to do any optimizations because the information is
> > implicit. Important optimization that could be achieved is eliminating the
> > cost of virtual call for leaf class pointer:
>
>
> In the linkage phase compiler knows pretty much every dynamic type on the call
> site and can decide whether generating non-virtual calls or inlining is
> beneficial or not.
>
True, a linker can again invoke the compiler and global optimizations
can be invoked done, but they are typically done at a higher levels of
optimization (in unix based compilers, higher than -O/+O2 optimization
levels). And such optimizations take lots of time since it involves
analysis across multiple compilation units. If final keyword were used,
then it can be done at low levels of optimizations, and compiler
doesn't need to do the hardwork - it can be made available by default.
Moreover, final documents the intent of the programmer - that he has
designed the class for direct use and not intended for use in
inheritance scenario (as base class).
thanks!
-Ganesh
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Thu, 22 Jun 2006 09:48:34 CST Raw View
wkaras@yahoo.com wrote:
> Alexei Alexandrov wrote:
> > Hi All!
> >
> > Are there any plans regarding adding the "final" keyword in C++ for specifying leaf classes in inheritance hierarchy? I mean, similar to what they have in Java. I know that there some tricks to achieve this in C++ today, but those tricks don't allow compiler to do any optimizations because the information is implicit. Important optimization that could be achieved is eliminating the cost of virtual call for leaf class pointer:
> >
> > class IDataManager
> > {
> > public:
> > virtual void doWork() = 0;
> > };
> >
> > final class DataManagerImpl : public IDataManager
> > {
> > virtual void doWork()
> > {
> > }
> > };
> >
> > void doSomething(DataManagerImpl *dataMgr)
> > {
> > // Compiler can perform statically resolved call here because
> > // the pointer is to final class and the call cannot be polymorphic
> > dataMgr->doWork();
> > }
> >
> > I faced such patterns several times when exposing the interface to external clients, but using the direct implementation pointer internally. I always kinda worry about redundant virtual call in such cases - I understand that it's negligible on modern architectures but still - it might be interesting.
> >
> > --
> > Alexei Alexandrov
>
> What are the advantages of using "final" as opposed to doing this:
>
> class A : public Base
> {
> .
> int final_x(int i);
> virtual int x(int i) { return(final_x(i)); }
> .
> };
>
> and then calling final_x instead of x for instances of A ?
Because it's horrible? What happens if someone creates a B which
inherits from A. Then those calls to final_x would start behaving
differently to the calls to x, but they look as thought they won't.
> It's clear that it would be desirable for the compiler to
> simply generate a single function with the (decorated)
> names A::final_x and A::x both tranlating to the start
> address of this (single) function.
I don't think that's at all true. 'final' implies that the author does
NOT intend the class to be inherited from. Though I think there's an
argument for saying that using a non-virtual destructor implies that
you don't intend the class to be inherited from, so you wouldn't really
need a final keyword.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Thu, 22 Jun 2006 09:56:59 CST Raw View
wkaras@yahoo.com wrote:
> What are the advantages of using "final" as opposed to doing this:
>
> class A : public Base
> {
> .
> int final_x(int i);
> virtual int x(int i) { return(final_x(i)); }
> .
> };
>
> and then calling final_x instead of x for instances of A ?
>
> It's clear that it would be desirable for the compiler to
> simply generate a single function with the (decorated)
> names A::final_x and A::x both tranlating to the start
> address of this (single) function.
>
It already exists:
A* p;
// initialize p
p->func(); // compilers will typically use late binding.
p->A::func(); // compilers use early binding.
Anyway, I fear that, if 'final' is added to the language, programmers
will abuse of this new keyword (uselessly reducing extensibility), as
they did in Java.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Fri, 23 Jun 2006 06:49:32 CST Raw View
SuperKoko wrote:
[...]
> Anyway, I fear that, if 'final' is added to the language,
> programmers will abuse of this new keyword (uselessly reducing
> extensibility), as they did in Java.
Interesting. From what I've seen of Java, just the opposite is
the case; most programmers don't bother to declare a function
final, even if they're not prepared to handle a different
implementation of it.
Unless you intentionally design a function to be replaced, it
generally cannot be robustly replaced. Almost none of the Java
programmers I've known, and very little of the code I've seen,
actually considers the issue. Which means that you cannot
override most functions and still be sure that the code works,
but the functions are not declared final.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Niklas Matthies <usenet-nospam@nmhq.net>
Date: Fri, 23 Jun 2006 09:55:44 CST Raw View
On 2006-06-23 12:49, kanze wrote:
> SuperKoko wrote:
:
>> Anyway, I fear that, if 'final' is added to the language,
>> programmers will abuse of this new keyword (uselessly reducing
>> extensibility), as they did in Java.
>
> Interesting. From what I've seen of Java, just the opposite is
> the case; most programmers don't bother to declare a function
> final, even if they're not prepared to handle a different
> implementation of it.
>
> Unless you intentionally design a function to be replaced, it
> generally cannot be robustly replaced.
Many uses of overrides delegate to the base implementation and
just do some additional stuff that doesn't affect the base object.
For example:
class HasAnnotatedFoo : public HasFoo
{
...
FooAnnotation myFooAnnotation;
public:
virtual void setFoo(Foo foo, FooAnnotation fooAnnotation)
{
HasFoo::setFoo(foo);
myFooAnnotation = fooAnnotation;
}
virtual void setFoo(Foo foo) // override
{
HasAnnotatedFoo::setFoo(foo, defaultFooAnnotation);
}
}
Another example is instrumentation of a base class method for e.g.
logging or notifications.
To keep classes open for extensions like these I rarely declare
methods final in Java unless it turns out there is a performance
bottleneck. I share SuperKoko's experience of having seen overuse of
'final' in Java where it would have been perfectly fine do have
certain "non-intrusive" overrides.
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: alfps@start.no ("Alf P. Steinbach")
Date: Fri, 23 Jun 2006 15:43:15 GMT Raw View
* kanze:
> SuperKoko wrote:
>
> [...]
>> Anyway, I fear that, if 'final' is added to the language,
>> programmers will abuse of this new keyword (uselessly reducing
>> extensibility), as they did in Java.
>
> Interesting. From what I've seen of Java, just the opposite is
> the case; most programmers don't bother to declare a function
> final, even if they're not prepared to handle a different
> implementation of it.
>
> Unless you intentionally design a function to be replaced, it
> generally cannot be robustly replaced. Almost none of the Java
> programmers I've known, and very little of the code I've seen,
> actually considers the issue. Which means that you cannot
> override most functions and still be sure that the code works,
> but the functions are not declared final.
I think the issue is much more complex than that. E.g., consider adding
tracing of member function calls for some pre-existing frozen class. I
think the complexity is so high that in a discussion of pro and con
every argument from one side could be countered by an argument from the
other side, and vice versa, ad nauseam and infinitum, and thus, I think
that disqualifies the notion of 'final' for member functions: when it's
that unclear, adding complexity to the language is IMO ungood.
As the OP noted there is already an idiom for 'final' for C++ classes
(it's in the FAQ). And the OP's argument is that language support could
allow optimizations. Well, I think it would be an optimization very
seldom "activated" for well-designed code, and in my humble opinion C++
has enough cases of making premature optimization all too easy.
So I think 'final' for classes is ungood too.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Alexei Alexandrov" <alexei.alexandrov@gmail.com>
Date: Sat, 17 Jun 2006 08:22:23 CST Raw View
Hi All!
Are there any plans regarding adding the "final" keyword in C++ for specifying leaf classes in inheritance hierarchy? I mean, similar to what they have in Java. I know that there some tricks to achieve this in C++ today, but those tricks don't allow compiler to do any optimizations because the information is implicit. Important optimization that could be achieved is eliminating the cost of virtual call for leaf class pointer:
class IDataManager
{
public:
virtual void doWork() = 0;
};
final class DataManagerImpl : public IDataManager
{
virtual void doWork()
{
}
};
void doSomething(DataManagerImpl *dataMgr)
{
// Compiler can perform statically resolved call here because
// the pointer is to final class and the call cannot be polymorphic
dataMgr->doWork();
}
I faced such patterns several times when exposing the interface to external clients, but using the direct implementation pointer internally. I always kinda worry about redundant virtual call in such cases - I understand that it's negligible on modern architectures but still - it might be interesting.
--
Alexei Alexandrov
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: benhongh@yahoo.com.au (benben)
Date: Sun, 18 Jun 2006 03:27:09 GMT Raw View
>
> void doSomething(DataManagerImpl *dataMgr)
> {
> // Compiler can perform statically resolved call here because
> // the pointer is to final class and the call cannot be polymorphic
> dataMgr->doWork();
What stops the compiler from doing such optimization anyway when no
class is found inheriting DataManagerImpl?
Even if there is no "final" tagged to DataManagerImpl, the mighty
compiler just knows that class is de-facto final.
Ben
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kalita@poczta.onet.pl ("Marcin Kalicinski")
Date: Sun, 18 Jun 2006 15:00:11 GMT Raw View
> What stops the compiler from doing such optimization anyway when no class
> is found inheriting DataManagerImpl?
>
> Even if there is no "final" tagged to DataManagerImpl, the mighty compiler
> just knows that class is de-facto final.
What about classes deriving from DataManagerImpl in other modules?
Marcin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: usenet-nospam@nmhq.net (Niklas Matthies)
Date: Sun, 18 Jun 2006 15:00:08 GMT Raw View
On 2006-06-18 03:27, benben wrote:
>>
>> void doSomething(DataManagerImpl *dataMgr)
>> {
>> // Compiler can perform statically resolved call here because
>> // the pointer is to final class and the call cannot be polymorphic
>> dataMgr->doWork();
>
> What stops the compiler from doing such optimization anyway when no
> class is found inheriting DataManagerImpl?
>
> Even if there is no "final" tagged to DataManagerImpl, the mighty
> compiler just knows that class is de-facto final.
In general the mighty compiler cannot know whether the program
doesn't at some point dynamically load some other module containing
a derivation of DataManagerImpl.
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: spam@spamguard.com ("Gene Bushuyev")
Date: Sun, 18 Jun 2006 17:30:18 GMT Raw View
"Alexei Alexandrov" <alexei.alexandrov@gmail.com> wrote in message
news:4fi5jeF1jji1nU1@individual.net...
> Hi All!
>
> Are there any plans regarding adding the "final" keyword in C++ for specifying
> leaf classes in inheritance hierarchy? I mean, similar to what they have in
> Java. I know that there some tricks to achieve this in C++ today, but those
> tricks don't allow compiler to do any optimizations because the information is
> implicit. Important optimization that could be achieved is eliminating the
> cost of virtual call for leaf class pointer:
There isn't anything preventing compiler/linker from resolving virtual calls to
non-virtual dispatch. Compiler in many cases, even for calls that are not to the
leaf classes is theoretically capable of optimizing away the virtual dispatch.
In the linkage phase compiler knows pretty much every dynamic type on the call
site and can decide whether generating non-virtual calls or inlining is
beneficial or not.
--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]