Is final used for optimization in C++?
Asked Answered
H

1

55
class A {
public:
    virtual void f() = 0;
};

class B : public A {
public:
    void f() final override { };
};

int main() {
    B* b = new B();
    b->f();
}

In this case, is the compiler required to still do the v-table lookup for b->f();, or can it call B::f() directly because it was marked final?

Highgrade answered 24/5, 2016 at 13:24 Comment(6)
class C : pubic A { void f() override; };Coruscate
new A() is ill-formed, because A is abstract.Coruscate
Look at devirtualization.Headstock
BTW, optimization are not required by the standard. There is the as-if rule which allows optimization.Headstock
Try e.g. class C : public B { void f() override {} };, and see what happens.Caber
The code you wrote in main is so simply that the compiler knows the target of the pointer and it can call the function directly, maybe also inlined as well. But yes, final is used in gcc to get better optimization. BUT: If you do not really know that nobody wants to derive from your class and overwrite some functionality, avoid final.Rhombohedral
P
51

Is final used for optimization in C++?

It can be, and is.

As noted, it is being used already; see here and here showing the generated code for the override with and without final.

An optimisation along these lines would relate to 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 to determine this, 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. given the OP example, with an automatic object), it could apply such an optimisation anyway, irrespective of whether the method is final or not.

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.

Parachronism answered 24/5, 2016 at 13:34 Comment(4)
This has been the answer for a long time, but is any compiler /actually/ using final for devirtualization?Ostensive
@JohanLundberg: Quick experimentation with the Compiler Explorer and locally shows that at least gcc 6.1, clang 3.8 and MSVC++2015U2 use the final keyword for devirtualization.Waxbill
For anyone curious I think this is where this optimization currently happens in clang: CodeGenFunction::CanDevirtualizeMemberFunctionCallWaxbill
@JohanJundberg There is an excellent blog serious from one of the gcc developers about devirtualization: hubicka.blogspot.de/2014/01/devirtualization-in-c-part-1.html. It also contains an explanation when final helps, and gcc introduced a warning for cases where adding finalwould enable optimizations which cannot be done otherwise.Sawyer

© 2022 - 2024 — McMap. All rights reserved.