现在,我知道内联没有保证,但......
鉴于以下内容:
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 table
B
我建议向GCC
bugzilla填写增强请求。