web-dev-qa-db-ja.com

C ++インライン関数?

なぜ私はこのようなことをする必要があります:

inline double square (double x) { return x*x;}

の代わりに

double square (double x) { return x*x;}

違いはありますか?

68
Pwnna

前者(inlineを使用)を使用すると、その関数をヘッダーファイルに配置して、複数のソースファイルに含めることができます。 inlineを使用すると、識別子をfile scopeで作成します。これは、staticを宣言するのとよく似ています。 inlineを使用しないと、リンカーから複数のシンボル定義エラーが発生します。

もちろん、これは、関数をコンパイルする必要があるというコンパイラーへのヒントに加えてinlineを使用する場所に(関数呼び出しのオーバーヘッドを回避するために)します。コンパイラは、inlineヒントに基づいて動作する必要はありません。

82
Greg Hewgill

はい、違いがあります。 https://isocpp.org/wiki/faq/inline-functions

関数がインラインであることを指定すると、コンパイラはメソッドのコードを呼び出される場所に配置します。

void myfunc() {
  square(2);
}

と同じです

void myfunc() {
   2 * 2;
}

関数を呼び出すとコードがわかりやすくなりますが、その関数が呼び出されると、ローカル状態をスタックにプッシュする必要があり、メソッドに新しいローカル状態が設定され、完了したら以前の状態をポップする必要があります。それは多くのオーバーヘッドです。

最適化レベルを上げると、コンパイラーはループの展開や関数のインライン化などの決定を行います。コンパイラーは、インラインステートメントを無視してもかまいません。

26
Erik Nedwidek

最近のコンパイラでは、おそらくそれほど違いはありません。 inlineなしでインライン化でき、notインライン化できますwithinline

23
Ben Jackson

ウィキペディアから:インライン関数は、コンパイラーがインライン展開の実行を要求された関数です。言い換えると、プログラマーは、定義された1つの場所で関数を呼び出すコードを生成するのではなく、関数が呼び出されるすべての場所に関数の完全な本体を挿入するようにコンパイラーに要求しました。コンパイラーはこの要求を尊重する義務はありません。

http://en.wikipedia.org/wiki/Inline_function

5

コンパイラーが準拠している場合、インライン関数は、関数が呼び出されていないかのように(呼び出し関数にロジックを配置したかのように)呼び出されたコードにインライン関数を含め、関数呼び出しのオーバーヘッドを回避します。

2
Ian Fleeton

inlineは、手続き抽象化の概念でうまく機能します。

inline double square (double x) { return x*x;}

int squareTwice(double x) {
    double first = square(x);
    double second = square(x);
    return first * second; 
}

上記は、基本的に次のものに似ています。

int squareTwice(double x) {
    double first = x*x;
    double second = x*x;
    return first * second; 
}

これは、コンパイラが関数呼び出しをインライン展開すると、関数のコードが呼び出し元のコードストリームに挿入されるためです。したがって、2番目の例を最初の例に手続き的に抽象化する方が簡単かもしれません。

手続きの抽象化により、ルーチンを読みやすい小さなサブルーチンに分割することができます(ただし、これはスタイルの選択になります)。

2
Gio Borje