インライン関数

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

インライン関数(Inline Function)とは、プログラミング言語の構文の一種で、コンパイラに対して特定の関数をインライン展開するよう指示するものである。つまり、コンパイラに対して、その関数を呼び出している全ての箇所に関数の実体を挿入するよう指示する。

意義[編集]

インライン展開は、関数呼び出しにかかるオーバーヘッドを無くす目的で行われる。一般に関数自体が非常に小さくオーバーヘッドの割合が無視できない場合に使われる。非常に小さい関数の場合、メモリ使用量を削減することもでき、各種最適化を施す上でも有利である。

インライン関数がない場合、プログラマはどの関数をインライン展開すべきかを指定できず、コンパイラが勝手に判断することになる。インライン関数機能があれば、そのアプリケーション固有の知識を元にして(どの関数がよく使われるかなど)、インライン展開すべき関数を決定できる。

また、言語によってはインライン関数はコンパイルモデルと密接に関連している。例えばC++では、インライン関数はモジュール単位に定義する必要がある(通常の関数は1つのモジュールで定義すればよい)。これにより、モジュール単位に独立したコンパイルができるようになっている。

マクロとの比較[編集]

C言語(C89)などでは、インライン展開をソースレベルの引数付きマクロで実現してきた。インライン関数はマクロに比べて次のような利点がある:

  • マクロ呼び出しは型チェックをしない。また、引数が正しい形式であるかもチェックしない。関数呼び出しではこれらがチェックされる。
  • C言語のマクロは単なる文字列の置換であり、予期せぬ副作用や、引数の評価を複数回行ってしまうことによる弊害が生じることがある。
  • マクロ内部でのコンパイラのエラーは、マクロ展開後のコードで発生するため、プログラマにとっては理解が難しくデバッグに時間がかかることがある。
  • マクロ内では構文が制限され、通常とは異なった書き方を要求される。インライン関数は通常の関数と全く同じであり、インライン化するかどうかも自由に決定できる。
  • インライン化されたコードのデバッグ情報はマクロを展開したコードよりも扱いやすい。
  • 多くのコンパイラではある種の再帰呼び出し関数もインライン展開できる。再帰的マクロは一般に不正である。

C++ の設計者ビャーネ・ストロヴストルップは、マクロよりもインライン関数を使うべきだと主張している。

言語サポート[編集]

C99C++ はインライン関数をサポートしている。ただし、Microsoft Visual C++ など、いまだ C89 までしか対応していないCコンパイラはインライン関数をサポートしていなく、Microsoft Visual C++ の場合は __inline キーワードで対応している。Microsoft Visual C++g++ などは、インライン関数として指定されていなくてもインライン展開すべき関数を自動的に展開するオプションを用意している。Ada では pragma をインライン関数として使うことができる。JavaJavaScript は言語仕様には存在しないが、JITコンパイラが最適化の一環でインライン展開することもある。関数型言語など他の多くの言語はインライン関数をサポートしていないが、インライン展開を積極的に行うことが多い。インライン展開の方針はコンパイラによって異なる。

C99/C++ ではインライン関数は次のように記述される:

inline int max (int a, int b)
{
    if (a > b)
        return a;
    else
        return b;
}
a = max (x, y); // これは、"a = (x > y ? x : y);" と等価となる

問題点[編集]

インライン展開にまつわる問題だけでなく、インライン関数は言語機能として積極的に使用されない一面がある。その理由は次の通りである:

  • 多くの場合、人間よりもコンパイラがインライン化すべき関数を決定する方がよい結果になる。人間がインライン化したいと考える関数よりもコンパイラがインライン化できると判断する関数の数が少ない場合は特にそうである。
  • プログラムの修正によって、かつてはインライン化すべきだった関数がインライン化すべきでないものになったり、逆の変化が起きたりする。これはマクロの場合も似たようなものだが、コードの保守という観点から見ればインライン関数にはあまり利点はない。
  • C言語でインライン関数を多用するとコンパイル時間が延びる傾向がある。これは関数の実体が呼び出している各所に埋め込まれて中間表現を形成するためである。コードサイズの増加はコンパイル時間の増加ももたらす。

インライン展開そのものの問題についてはインライン展開の欠点を参照されたい。

関連項目[編集]

外部リンク[編集]