2017-11-23 4 views
1

How does the compiler benefit from C++'s new final keyword? この質問に記載されているように、メソッドのキーワードfinalでは、vtable呼び出しを単純な関数ポインタで最適化できます。最終クラスのメソッドは、デフォルトで関数最適化へのポインタに適用されますか?

私はクラスを持っている場合:

class Derived final : public Base 
{ 
virtual void Foo() override; 
//virtual void Foo() final override; Are these statements equal? 
} 

は最終としてマークこのような方法をコンパイラや代わりのvtableの関数ポインタを適用するのでしょうか? vc120とclangコンパイラの動作に興味があり、最高の最適化レベルが設定されています。

+0

クラスは 'final'なので、もはやそれを継承することができないので、派生クラスの仮想メソッドをオーバーライドすることはできません。 – Jarod42

+0

@ Jarod42、はい、私は質問タイトルをアップグレードしました。私は最適化の適用について質問に興味があります –

+0

as-ifルールを尊重する限り、最適化を適用するのはコンパイラによるものです。私は両方の形式からコンパイラを等しく最適化することを期待します。 – Jarod42

答えて

3

コンパイラが演繹を停止することは何もありません。Fooをさらに上書きすることはできません。

struct Base { 
    virtual void Foo() = 0; 
}; 

struct Derived final : public Base 
{ 
virtual void Foo() override {} 
//virtual void Foo() final override; Are these statements equal? 
}; 

Derived* getD(); 

int main() { 

    getD()->Foo(); 

    return 0; 
} 

それはこの(Live on godbolt)を生成:

main:         # @main 
     push rax 
     call _Z4getDv 
     mov  rdi, rax 
     call _ZN7Derived3FooEv 
     xor  eax, eax 
     pop  rcx 
     ret 
_ZN7Derived3FooEv:      # @_ZN7Derived3FooEv 
     ret 

あなたが見ることができるように、あなたがあなたの質問にクランを指定したので、ここで私は-O1とクラン5でテストされたサンプルコードですコンパイラは完全にそれをDerived::Fooを直接呼び出すことができると推測することができます。

+0

私が知っているように、 'final'がコードになくても、オプティマイザはvtableを関数呼び出しに置き換えることもできます。 'final'はデザインキーワード(' override'など)であり、基本的な目標は最適化ではありませんが、 'final'によって提供される情報を使っていくつかの場所を最適化することができます。右? –

+0

@BohdanBessonov - 一般的な仮想関数がオーバーライドされていないことを証明するには、プログラム全体の解析が必要です(また、DLLから来るインターフェースについて考える)。それは一般的に扱いにくいです。しかし、コンパイラは 'final'指定子**がオーバーライドを保証しないことを知っているので、問題は簡単に解決できます。だから、これは非常に貴重な指定子です。 – StoryTeller

関連する問題