Visual C++:在明显的情况下没有机会

Visual C++ : No devirtualization in obvious cases?

本文关键字:情况下 机会 C++ Visual      更新时间:2023-10-16

在观看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

对于临时案件和成员案件,似乎没有出现任何机会。那么,这是编译器实现质量的问题,还是有技术上的正当理由导致这样的结果?

只是错过了机会不足的案例。自从支持去机会化的第一个版本,即VS 2013以来,情况一直如此。其他编译器gcc、icc和clang在所有情况下都执行去机会化。一般来说,最好显式指定final,而不是依赖编译器来学究式地执行虚拟化。用final标记Impl.foo可以实现所有情况下的优化。