5.22 関数の自動インライン展開とスタティック関数

最適化レベルが -O2 および -O3 の場合、または --autoinline が指定されている場合、コンパイラは、関数が __inline または inline と宣言されていない場合でも、関数をインライン展開することが実際的かつ可能であれば、自動的に関数をインライン展開できます。

これは、スタティック関数のすべての使用をインライン展開できる場合にはアウトオブラインコピーが必要ないので、スタティック関数に適しています。関数が static (または __inline)として明示的に宣言されていない限り、コンパイラは、他のモジュールから呼び出された場合に備え、オブジェクトファイル内の関数のアウトオブラインバージョンを保持する必要があります。
非インライン関数が定義されている変換単位の外部で使用されない場合は、すべての非インライン関数を static としてマークして下さい(変換単位は、ソースファイルのプリプロセッサ出力と、 #include ディレクティブの結果としてインクルードされるすべてのヘッダおよびソースファイルを合わせたものです)。通常、非インライン関数の定義はヘッダファイル内には配置しません。
モジュールの外部から呼び出されない関数を static として宣言しなかった場合、コードが悪影響を受けることがあります。具体的には以下のデメリットが挙げられます。
  • コードサイズの増大(関数のアウトオブラインバージョンはイメージ内に保持されるため)。
    関数が自動的にインライン展開されると、関数が static として宣言されていなければ、そのインラインバージョンとアウトオブラインバージョンの両方が最終イメージに含まれる可能性があります。これは、コードサイズ増大の原因になる場合があります。
  • 無駄に複雑化したデバッグビュー(関数のインラインバージョンとアウトオブラインバージョンの両方が表示されるため)。
    関数のインラインコピーとアウトオブラインコピーの両方をコード内に保持すると、ブレークポイントの設定時またはデバッグビューでのシングルステップ実行時に混乱を招きかねません。デバッガは、ユーザがインラインバージョンとアウトオブラインバージョンのいずれかをステップ実行する際に何が起こっているかを確認できるように、インターリーブされたソースビューでインラインバージョンとアウトオブラインバージョンの両方を表示する必要があります。
このような問題のため、別のモジュールから呼び出されることが決してないと確信できる非インライン関数については、 static として宣言することが重要です。
関連する概念
5.20 インライン関数
5.21 関数のインライン展開に関するコンパイラによる決定
5.23 インライン関数と、リンク時における未使用のアウトオブライン関数の削除
5.24 関数の自動インライン展開とマルチファイルのコンパイル
5.26 コンパイラモードとインライン関数
5.27 C++ および C90 モードでのインライン関数
5.28 C99 モードでのインライン関数
5.29 インライン関数とデバッグ
関連する参考文書
5.25 関数のインライン展開に関するコンパイラの決定をオーバーライドすることの制限
8.15 --autoinline、--no_autoinline
8.139 -Onum
非機密扱いPDF file icon PDF 版ARM DUI0472LJ
Copyright © 2010-2015 ARM.All rights reserved.