私はずっと前に、キーワードinlineを使用し、ヘッダーファイルに本文を書き込むことによって、インラインで頻繁に呼び出される短い関数/メソッドを作成するように言われました。これは、実際の関数呼び出しのオーバーヘッドがないようにコードを最適化するためでした。
今日はどうですか?最新のコンパイラ(この場合はVisual Studio 2010)は、このような短い関数を自動的にインライン化しますか、それとも自分でインライン化する必要がありますか?
私はずっと前に、キーワードinlineを使用し、ヘッダーファイルに本文を書き込むことによって、インラインで頻繁に呼び出される短い関数/メソッドを作成するように言われました。これは、実際の関数呼び出しのオーバーヘッドがないようにコードを最適化するためでした。
今日はどうですか?最新のコンパイラ(この場合はVisual Studio 2010)は、このような短い関数を自動的にインライン化しますか、それとも自分でインライン化する必要がありますか?
inline
は常にコンパイラーへのヒントであり、最近のコンパイラーはほとんどの場合、この点に関して独自の決定を下します(を参照register
)。
関数をインラインで展開するには、コンパイラーはその関数の定義を確認する必要があります。1つの変換単位でのみ定義および使用される関数の場合、問題はありません。定義を使用する前のどこかに置くと、コンパイラが関数をインライン化するかどうかを決定します。
複数の変換ユニットで使用される関数の場合、コンパイラーが関数の定義を確認するには、定義をヘッダーファイルに入れる必要があります。その場合、関数にマークを付けて、inline
その関数の定義が複数あることをコンパイラとリンカに通知する必要があります。(まあ、あなたは関数を作ることができると思いますがstatic
、そうするとあなたは複数のコピーでスペースを無駄にすることになりかねません)
一般的に、inline
キーワードは、コンパイラーにインライン化に関するヒントを与えるよりも、ヘッダーで関数を定義するときに1つの定義規則に「違反」できるようにするために使用されるようになりました。多くのコンパイラは、関数本体が呼び出しポイントで表示されている限り、関数をインライン化するかどうかを決定するのに非常に優れています。
もちろん、関数を非インラインのソースファイルでのみ定義する場合、コンパイラはその1つのソースファイルで関数をインライン化できますが、他の変換ユニットではインライン化できません。
インライン化は、次の状況でコンパイラによって実行される場合があります。
inline
関数をととしてマークしました
このキーワードは、インライン展開が優先
inline
されることをコンパイラーに通知します。 コンパイラーは、インライン展開オプションとキーワードを提案として扱います。
__forceinline
キーワード(または__ attribute __((always_inline))
gcc)を使用しました。これにより、コンパイラはいくつかのチェックをスキップしてインライン化を実行します。
キーワードは費用便益分析を上書きし、
__forceinline
代わりにプログラマーの判断に依存します。
コンパイラまたはリンカにフラグを渡すことによってリンク時コード生成をオンにした場合、Microsoftコンパイラはクロスモジュールインライン化を実行することもできます。このような最適化を行うのは非常に賢い方法です。でコンパイルされたモジュールのアセンブリコードを調べてみてください。/GL
/LTCG
/LTCG
関数が次の場合、インライン化は発生しないことに注意してください。
はい。最近のコンパイラは、(ヘッダーではなく)ソースファイルにある場合でも、(さまざまな構成オプションに応じて)自動的にインライン関数を選択します。インラインディレクティブを使用すると、ヒントが得られます。
あなたの要点(今日のコンパイラーの時点でコードにインライン命令を配置する量が役立つ)は別として、インライン関数はコンパイラーへの単なるヒントであり、必ずしもインラインとしてコンパイルされているわけではないことに注意してください。
つまり、はい、コンパイラは関数がになるかどうかを決定しますinline
。あなたはこの質問をチェックすることができます: