在观看由visual c ++(VS2017 RC)生成的代码时,我很惊讶在简单的情况下看到动态分支(虚拟调用)。
所以我用编译器资源管理器尝试了以下代码:
struct Base
{
virtual void foo() = 0;
};
struct Impl : Base
{
void foo() override;
};
Impl g_impl;
void globalCall()
{
g_impl.foo();
}
void localCall()
{
Impl i;
i.foo();
}
void tempCall()
{
Impl().foo(); // dynamic branching generated!
}
struct Class
{
void memberCall();
Impl impl;
};
void Class::memberCall()
{
impl.foo(); // dynamic branching generated!
}
编译器资源管理器链接: https://godbolt.org/g/RmUku2
对于临时和成员案例,看起来没有发生虚拟化。那么它是一个编译器质量的实现问题,还是有这种结果的技术有效原因?
答案 0 :(得分:1)
错过了虚拟化的案例。从支持虚拟化的第一个版本开始就是这样,即VS 2013.其他编译器gcc,icc和clang在所有情况下执行虚拟化。通常,最好明确指定final
而不是依赖编译器来迂腐地执行虚拟化。使用Impl.foo
标记final
可以在所有情况下进行优化。