Visual C++:在明显的情况下没有虚拟化?

RTe*_*ete 6 c++ compiler-optimization visual-studio

在观看由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!
} 
Run Code Online (Sandbox Code Playgroud)

编译器资源管理器链接:https: //godbolt.org/g/RmUku2

对于临时和成员案例,看起来没有发生虚拟化.那么它是编译器质量的实现问题,还是有这种结果的技术上有效的原因?

Had*_*ais 1

只是错过了去虚拟化的案例。从第一个支持去虚拟化的版本 VS 2013 开始就是这样。其他编译器 gcc、icc 和 clang 在所有情况下都执行去虚拟化。一般来说,最好是显式指定final,而不是依赖编译器迂腐地执行去虚拟化。标记Impl.foofinal可以在所有情况下进行优化。