2017-01-31 7 views
6

Visual C++(VS2017 RC)で生成されたコードを見て、単純なケースで動的分岐(仮想呼び出し)を見ていると非常に驚いていました。何devirtualizationが発生していないように見える、一時的およびメンバーケース付き https://godbolt.org/g/RmUku2Visual C++:明白なケースでは、非揮発性化はありませんか?

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! 
} 

コンパイラエクスプローラリンク:

は、だから私は、コンパイラエクスプローラで次のコードを試してみました。それでは、コンパイラの実装上の問題ですか、そのような結果の技術的な正当な理由はありますか?

+1

「final」を追加しましたか? – Yakk

答えて

1

仮想化を見逃してしまった。それはdevirtualizationがサポートされた最初のバージョン、つまりVS 2013以来、このようになっています。他のコンパイラgcc、icc、およびclangは、すべてのケースでデボルゴ化を実行します。一般的には、コンパイルに頼るのではなく、ぼんやりとした仮想化を実行するのではなく、finalを明示的に指定する方がよいでしょう。 Impl.foofinalとマークすると、すべてのケースで最適化が可能になります。

関連する問題