2017-02-16 11 views
1

私はこのようなC++クラスがあります。このように使用されてコンパイラはメソッド呼び出しを最適化できますか?

class MyClass { 
    int calculate(int arg1) const; 
    void side_effect(int arg) const; 
} 

{ 
    MyClass m; 
    m.calculate(100); 
    m.side_effect(100); 
} 

は、コンパイラの自由がm.calculate()呼び出しをスキップです - 私は、戻り値を保持しないので? side_effect()メソッドについては、コンパイラが呼び出しをスキップできないことを本当に願っています - メソッドにはconstとマークされていますが?

編集:私はこの質問を理由は、私のcalculate()関数が副作用を持っていますが、mutableを使用して、それがconstとしてマークされていることです。さて、通常の場合、私は戻り値を保持したい、そして全体的な問題は疑問ですが、上記の例では、副作用が呼び出されたことを確かめることにのみ関心があります(はい - それはかなり...)。回答/コメントを読む私は、コンパイラがメソッドに副作用があるかどうかを推測できると感じています。それは私には驚きでしたか?

+2

結果は、関数が呼び出されたときと同じでなければなりません。効果がない場合は、どのように違いを伝えることができますか? –

答えて

5

m.calculate()によって異なります。

値が取得されてから離れてしまった場合、実際にコンピュータがここで行うことは役に立たず、完成したプログラムでも通話がうまくいかない場合があります。

しかし、コンパイラが最適化を実行できる範囲は、とりわけ関数の定義の可視性によって制限されます。

constとは関係ありません。したがって、m.side_effect()に副作用がある場合、スキップすることはできません。

0

コンパイル時に、実行時に効果のないコードが最適化されます。決して呼び出されないブランチと決して使用されない値。 Constデータとオブジェクトは、その値がコンパイル時にわかっているので、ここで便利です。メソッド自体にconstを置いてもそれは変わりません。つまり、このメソッドがオブジェクトを変更しないことを知っているということです。オブジェクト自体はまだconstではないので、メソッドがconstであっても、メソッドの実行時にデータ値が何であるかを100%認識することはありません。非constメソッドがオブジェクトをある時点で変更した可能性はまだあります。

さらに、そのようなクラスで宣言されたメソッドはインラインであり、関数呼び出しの代わりにコード自体に置き換えられます。 side_effectメソッドが行う「アクション」が何であれ、関数呼び出し自体の代わりにコードに直接書き込まれます。実際に何もしない限り、全体が最適化されず、問題になることはありません。

BTW。 constメソッドは依然として関連オブジェクトに影響を与える可能性があります。クラス内のポインタを介してデータにアクセスすると、ポインティングされたデータを自由に変更できますが、ポインタ自体のアドレスは変更できません。

+1

"関数呼び出しの代わりにコード自体に置き換えられます。 ** **コードで置き換えられるかもしれません。 'inline'メソッドをインラインで確かめることを聞いたコンパイラはありません。コンパイル中に何が良いかを決定します。 – riodoro1

0

「缶」と「はず」を区別してみましょう。 「可能」に関しては、コンパイラがいくつかのコード生成コードを最適化する能力は、コード設計とコンパイラがどのように「スマート」であるかによって異なります。コンパイラが持っているヒントが増えるにつれ、より厳密には何かを最適化できるようになります。あなたのケースでは

、機能side_effectcalculateはダミーであり、何を行う(とcalculateが静的​​にハードコード値を返します)していない場合、彼らはアウトに最適化することができます。それ以外にも、パラメータを宣言し定義した場所で最適化することができます(この場合は 'should'と混同しないでください)。しかし、このような理由から(特にシンプルなコンパイラが使用されている場合は特に)、値渡しではなくintへのconst参照として宣言するパラメータについて、より多くのヒントを与える必要があるでしょう。この場合

、あなたのコード

MyClass m; 
m.calculate(100); 
m.side_effect(100); 

は機能のために、またそれらのパラメータのためにどちらも実行可能にする命令を生成しません。

また、constを指定すると、コンパイラがいくつかのコードを最適化することは強制されませんが、コードを最適化する必要があるときにコンパイラがコードを最適化できるようになります。

関連する問題