Does using specifier final
on a class
or on a function
add any memory or cpu overhead, or is it used at compile time only?
And how does std::is_final
recognise what is final?
Marking your classes or member functions as final can improve the performance of your code by giving the compiler more opportunities to resolve virtual calls at compile time.
Final keyword in C++ when added to a function, prevents it from being overridden by derived classes. Also when added to a class prevents inheritance of any type.
It actually can reduce overhead. And in rare cases, increase it.
If you have a pointer to a final
class A
, any virtual method calls can be de-virtualized and called directly. Similarly, a call to a virtual final
method can be de-virtualized. In addition, the inheritance tree of a final
class is fixed, even if it contains virtual
parent classes, so you can de-virtualize some parent access.
Each of these de-virtualizations reduce or eliminate the requirement that a run-time structure (the vtable) be queried.
There can be a slight downside. Some coding techniques rely on vtable access to avoid direct access to a symbol, and then do not export the symbol. Accessing a vtable can be done via convention (without symbols from a library, just the header file for the classes in question), while accessing a method directly involves linking against that symbol.
This breaks one form of dynamic C++ library linking (where you avoid linking more than a dll loading symbol and/or C linkage functions that return pointers, and classes are exported via their vtables).
It is also possible that if you link against a symbol in a dynamic library, the dynamic library symbol load could be more expensive than the vtable lookup. I have not experienced or profiled this, but I have seen it claimed. The benefits should, in general, outweigh such costs. Any such cost is a quality of implementation issue, as the cost is not mandated to occur because the method is final
.
Finally, final
inhibits the empty base optimization trick on classes, where someone knows your class has no state, and inherits from it to reduce the overhead of "storing" an instance of your class from 1 byte to 0 bytes. If your class is empty and contains no virtual methods/inheritance, don't use final
to avoid this being blocked. There is no equivalent for final
functions.
Other than the EBO optimization issue (which only occurs with empty types), any overhead from final
comes from how other code interacts with it, and will be rare. Far more often it will make other code faster, as directly interacting with a method enables both a more direct call of the method, and can lead to knock-on optimizations (because the call can be more fully understood by the compiler).
Marking anything except an empty type as final
when it is final is almost certainly harmless at run time. Doing so on classes with virtual functions and inheritance is likely to be beneficial at run time.
std::is_final
and similar traits are almost all implemented via compiler built-in magic. A good number of the traits in std
require such magic. See How to detect if a class is final in C++11? (thanks to @Csq for finding that)
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