派生 class 时的 C++ 虚函数内联是最终的?

C++ virtual function inlining when derived class is final?

我在嵌入式环境中使用 C++,其中虚拟函数的运行时间很重要。我读过关于可以内联虚函数的罕见情况,例如:Are inline virtual functions really a non-sense? 接受的答案指出,只有在运行时知道确切的 class 时,内联才有可能,例如在处理本地、全局或静态对象(不是指针或对基类型的引用)时。我理解这背后的逻辑,但我想知道在以下情况下是否也可以进行内联:

class Base {

    public:

        inline virtual void x() = 0;
}

class Derived final : Base {

    public:

        inline virtual void x(){
            cout << "inlined?";
        }
}

int main(){
    Base* a;
    Derived* b;

    b = new Derived();
    a = b;

    a->x(); //This can definitely not be inlined.
    b->x(); //Can this be inlined?
}

从我的角度来看,编译器应该在编译时知道 a 的最终类型,因为它是最终的 class。在这种情况下是否可以内联虚函数?如果不是,那为什么呢?如果是,那么 gcc 编译器(分别是 avr-gcc)是否这样做?

谢谢!

第一步叫做去虚拟化;函数调用不通过虚拟分派的地方。

编译器可以并且确实将 final 方法和 final 类 的方法去虚拟化。这几乎就是决赛的全部意义了。

去虚拟化后,可以内联方法。

有些编译器有时可以证明 *a 的静态类型,甚至可以将其去虚拟化。这不太可靠。 Godbolt 的编译器资源管理器可用于了解可能发生哪些特定优化以及如何失败。