调用不是内联的常量指针到成员函数

Gab*_*cia 6 c++ c++11

现在,我知道内联没有保证,但......

鉴于以下内容:

struct Base {
    virtual int f() = 0;
};

struct Derived : public Base {
    virtual int f() final override {
        return 42;
    }
};

extern Base* b;
Run Code Online (Sandbox Code Playgroud)

我们有:

int main() {
    return static_cast<Derived*>(b)->f();
}
Run Code Online (Sandbox Code Playgroud)

编译为:

main:
    movl    $42, %eax
    ret
Run Code Online (Sandbox Code Playgroud)

然而...

int main() {
    return (static_cast<Derived*>(b)->*(&Derived::f))();
}
Run Code Online (Sandbox Code Playgroud)

编译为:

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    b, %eax
    movl    (%eax), %edx
    movl    %eax, (%esp)
    call    *(%edx)
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

哪个真的很难过.

为什么没有内联PMF的调用?PMF是一个不变的表达!

小智 5

这里的问题是,在第一种情况下,基于类型的去虚拟化将间接调用转换为直接调用。当您添加成员指针时,不能使用基于类型的去虚拟化(因为它通过前端向下传递到有关被调用的类型和虚拟方法的优化信息来工作,这在这种情况下是不常见的)。 通过知道它是一个类并且知道它的成员只能在它被构造后才能被调用,GCC也许能够不断地将实际访问折叠起来。目前它不做这样的分析。virutal tableB

我建议向GCCbugzilla填写增强请求。