サーチ…
前書き
inline
指定子で定義された関数は、インライン関数です。インライン関数は、 1つの定義ルールに違反することなく多重定義することができます。したがって、外部リンケージを使用してヘッダーで定義することができます。関数のインラインヒントをコンパイラに宣言すると、コード生成中に関数をインライン化する必要がありますが、保証は提供されません。
構文
-
inline
function_declaration -
inline
function_definition - クラス{function_definition};
備考
通常、関数用に生成されたコードが十分に小さい場合、それはインライン化するのに適しています。なぜそうなのか?関数が大きく、ループ内でインライン化された場合、すべての呼び出しに対して、大きな関数のコードが複製され、生成されたバイナリサイズが膨らんでしまう。しかし、どのくらいのもので十分ですか?
インライン関数は、オーバーヘッド関数呼び出しを回避するための素晴らしい方法であると思われるが、それはマークされているすべての関数ではないことに留意すべきだinline
インライン化されています。言い換えれば、 inline
で言うと、それは命令ではなく、コンパイラのヒントにすぎません。コンパイラは関数をインライン化する必要はなく、無視することは自由です。現代のコンパイラはこのような最適化を行う方が優れています。このキーワードは、プログラマによる関数インライン化の提案がコンパイラによって真剣に受け止められた過去の痕跡です。マークされていないとしても機能inline
、それはそうすることで利益を見たとき、コンパイラによってインライン化されています。
リンケージ指令としてのインライン
現代のC ++のinline
のより実用的な使用法は、それをリンケージ指令として使用することから来ています。宣言ではなく、複数のソースにインクルードされるヘッダー内の関数を定義すると 、各翻訳単位にはこの関数の独自のコピーがあり、 ODR (One Definition Rule)違反となります。この規則は、関数、変数などの定義が1つしかないことを大まかに示しています。この違反を回避するために、関数定義をinline
でマークすると、暗黙的に関数のリンケージが内部になります。
よくある質問
C ++で関数/メソッドのキーワード「インライン」を書くべきはいつですか?
ヘッダーに関数を定義したいときのみ。より正確には、関数の定義が複数のコンパイル単位で表示される場合のみです。コンパイラにコードを最適化しながら作業するための詳細情報を与えるので、ヘッダファイルに小さな関数を定義することをお勧めします。コンパイル時間も長くなります。
C ++で関数/メソッドのキーワード 'inline'を書くべきではありませんか?
コンパイラがインライン展開すると、コードがより速く実行されると思うときは、 inline
追加しないでください。
関数/メソッドをいつインライン化するかはコンパイラがいつ認識しますか?
一般的に、コンパイラはこれをあなたよりも優れたものにすることができます。ただし、関数定義を持たないコンパイラには、コードをインライン化するオプションはありません。最大限に最適化されたコードでは、通常はすべてのプライベートメソッドがインライン展開されます。
関連項目
非メンバーインライン関数宣言
inline int add(int x, int y);
メンバー以外のインライン関数定義
inline int add(int x, int y)
{
return x + y;
}
メンバーインライン関数
// header (.hpp)
struct A
{
void i_am_inlined()
{
}
};
struct B
{
void i_am_NOT_inlined();
};
// source (.cpp)
void B::i_am_NOT_inlined()
{
}
関数インライン化とは何ですか?
inline int add(int x, int y)
{
return x + y;
}
int main()
{
int a = 1, b = 2;
int c = add(a, b);
}
上記のコードでは、 add
がインライン展開されると、結果のコードは次のようになります
int main()
{
int a = 1, b = 2;
int c = a + b;
}
インライン関数はどこにも見えません。その本体は呼び出し元の本体にインライン展開されます。たadd
インライン化されていない、関数が呼び出されます。新しいスタックフレームの作成、引数のコピー、ローカル変数の作成、ジャンプ(キャッシュミスによる参照のローカリティの損失)など、関数を呼び出すオーバーヘッドが発生する必要があります。