GNU GCCには、gcc のインライン化オプションと決定プロセスのかなり良い概要があります。
これにより、インライン化が不可能なケースが特定されます。「varargs の使用、alloca の使用、可変サイズのデータ型の使用、計算された goto の使用、非ローカル goto の使用、およびネストされた関数」
重要な点は非静的関数です。つまり、extern
リンケージを持つ関数 ( なしで宣言されたすべての関数static
) を呼び出すか、そのアドレスを別のソース ファイルに取得することができます。
これにより、コンパイラは「通常の」関数とインライン化された関数本体を強制的に生成します。もちろん、これは「通常の」非インライン関数を生成するだけよりも大きなプログラムを生成します。
Gccには、リンカーが使用されていない関数を削除できるようにするオブジェクトファイルを生成するオプションがあります-ffunction-sections
が、「... アセンブラーとリンカーはより大きなオブジェクトと実行可能ファイルを作成し、速度も遅くなります。」
gcc の最近のバージョンでは、Link Time Optimisations (LTO) ( 「プログラム全体の最適化」を参照) がサポートされています。これにより、最適化段階でコンパイルされたすべてのプログラムを調べ、さらに積極的なインライン化と最適化を行い、未使用のコードを除外できます。
新しいgcc-4.6 gcc-4.7手続き間の最適化のいくつかを見るのも興味深いことです。たとえば、関数全体ではなく、インライン関数の「ホット パス」のみをインライン化します。定数が既知であるため、Gcc は 1 つの関数の複数のインスタンスを生成することもあり、gcc は、既知の定数に対してそれぞれが最適化された複数の実装を持つ方がよいと計算します。
gcc には、すべての「単純な」関数をインライン化するようコンパイラーに要求するオプションがあります。
最後に、「ISO C ++で必要とされるように、GCCは、クラスの本体内で定義されたメンバー関数が、インラインキーワードで明示的に宣言されていなくても、インラインでマークされていると見なします」と述べています。その場合、「十分に単純」というルールが使用されます。
要約: コンパイラは、通常の関数やインライン関数から期待される以上の非常に巧妙な最適化を行う場合があります。