struct base {
virtual void vcall() = 0;
};
struct foo final : base {
void vcall() final;
};
void call_base(base& b) {
b.vcall();
}
void call_foo(foo& f) {
call_base(f);
}
void call_foo_directly(foo& f) {
f.vcall();
}
clang 16产生:
call_base(base&):
mov rax, qword ptr [rdi]
jmp qword ptr [rax]
call_foo(foo&):
mov rax, qword ptr [rdi]
jmp qword ptr [rax]
call_foo_directly(foo&):
jmp foo::vcall()@PLT
GCC和MSVC产生相同的结果,所以这不是仅限于clang的问题。难道call_foo
不应该也包含对foo::vcall()
的非虚拟调用吗?这是一个错过的优化,还是呼叫可能是虚拟的?
参见live example on Compiler Explorer。
1条答案
按热度按时间mnemlml81#
编译器确实尝试了,但是需要内联一些东西,如果一个函数没有实现,它只是一个空调用,这就是编译的内容;添加
final
只是防止以后使用override
。为了编译它,优化volatile
是有点需要的,所以一切都不会被优化掉。在bodbolt上查一下。
这是带有-O3部分拆卸的叮当-15(与-O2相同); vs无法内联
call_foo
。