C++11 added final.
Finally!
I understand final
does two things:
Both of these seem independent of each other. But take for example the following:
class Foo
{
public:
virtual void bar()
{
//do something unimportant.
}
};
class Baz final : public Foo
{
public:
void bar() /*final*/ override
{
//do something more important than Foo's bar.
}
};
From above, I believe Baz
being final
, I should NOT need to specify that its virtual
member function bar
is also final
. Since Baz
cannot be inherited, the question of overriding bar
goes out of scope. However my compiler VC++ 2015, is very quiet about this. I have not tested this on any others at the moment.
I would be glad if someone could shed some light on this topic. A quote from the standard (if any) would be extremely appreciated. Also please state any corner cases that I am unaware of, that may cause my logical belief to fail.
So, my question is: Does a final class
implicitly imply its virtual
functions to be final
as well? Should it? Please clarify.
The reason I am asking this is because final
functions become qualified for de-virtualization, which is a great optimization. Any help is appreciated.
to consider every aspect of a problem. 3. the way in which a problem, idea, etc, may be considered. to consider a problem from every aspect.
That depends on each company's organizational structure. Usually Vice Presidents (VPs) and Senior Vice Presidents (SVPs) report to C-level executives. For example, the VP of Product Marketing and the VP of Digital Marketing will report to the CMO. D-level executives are the ones who report to VPs.
tinguishes seven aspects of meaning: discoursal, lexical, morphological, propositional, syntactic, rhetorical, and functional meaning.
This metric measures the amount of time a company takes to turn money invested in operations into cash. The CCC uses the average times to pay suppliers, create inventory, sell products, and collect customer payments. Generally, the shorter this timeframe is, the better it is for the company.
The reason I am asking this is because final functions become qualified for de-virtualization, which is a great optimization.
Do they? "De-virtualization" is not part of the C++ standard. Or at least, not really.
De-virtualization is merely a consequence of the "as if" rule, which states that the implementation can do whatever it likes so long as the implementation behaves "as if" it is doing what the standard says.
If the compiler can detect at compile-time that a particular call to a virtual member function, through a polymorphic type, will undeniably call a specific version of that function, then it is allowed to avoid using the virtual dispatching logic and calling the function statically. That's behaving "as if" it had used the virtual dispatching logic, since the compiler can prove that this is the function that would have been called.
As such, the standard does not define when de-virtualization is allowed/forbidden. A compiler, upon inlining a function that takes a pointer to a base class type, may find that the pointer being passed is pointing to a stack variable local declared in the function that it is being inlined within. Or that the compiler can trace down a particular inline/call graph to the point of origin for a particular polymorphic pointer/reference. In those cases, the compiler can de-virtualize calls into that type. But only if it's smart enough to do so.
Will a compiler devirtualize all virtual function calls to a final
class, regardless of whether those methods are declared final
themselves? It may. It may not. It may not even devirtualize any calls to methods declared final
on the polymorphic type. That's a valid (if not particularly bright) implementation.
The question you're asking is implementation specific. It can vary from compiler to compiler.
However, a class being declared final
, as you pointed out, ought to be sufficient information for the compiler to devirtualize all calls to pointers/references to the final
class type. If a compiler doesn't do so, then that's a quality-of-implementation issue, not a standards one.
To quote the draft C++ standard from here [class.virtual/4]:
If a virtual function
f
in some classB
is marked with the virt-specifierfinal
and in a classD
derived fromB
a functionD::f
overridesB::f
, the program is ill-formed.
And here [class/3]:
If a class is marked with the class-virt-specifier
final
and it appears as a base-type-specifier in a base-clause (Clause [class.derived]), the program is ill-formed.
So, in answer to the question;
Does a
final
class
implicitly imply itsvirtual
functions to befinal
as well? Should it? Please clarify.
So, at least not formally. Any attempt to violate either rule will have the same result in both cases; the program is ill-formed and won't compile. A final class
means the class cannot be derived from, so as a consequence of this, its virtual
methods cannot be overridden.
Should it? At least formally, probably not; they are related but they are not the same thing. There is also no need formally require the one to imply the other, the effect follows naturally. Any violations have the same result, a failed compilation (hopefully with appropriate error messages to distinguish the two).
To touch on your motivation for the query and the de-virtualization of the virtual calls. This is not always immediately affected by the final
of the class nor method (albeit they offer help), the normal rules of the virtual functions and class hierarchy apply.
If the compiler can determine that at runtime a particular method will always be called (e.g. with an automatic object, i.e. "on the stack"), it could apply such an optimisation anyway, irrespective of the method being marked final or not. These optimisations fall under the "as-if" rule, that allow the compiler to apply any transformation so long as the observable behaviour is as-if the original code had been executed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With