inline 関数指定子
インライン関数を宣言します。
目次 |
[編集]構文
inlinefunction_declaration | (C99以上) | ||||||||
[編集]説明
inline
指定子の意図は、関数の定義が呼び出し元に可視であることを要求する最適化 (インライン化など) を行うように、コンパイラに対するヒントを提供することです。 コンパイラは最適化の目的に対して inline
指定子の有無を無視することができます (そして、通常、無視します)。
コンパイラが関数のインライン化を行う場合は、その関数の呼び出しをその本体で置き換え、関数呼び出しのオーバーヘッドを回避します (スタックにデータを置き、結果を取得します)。 これは、同じ関数を複数回呼ぶ必要があるコードの場合、実行可能ファイルを大きくする可能性があります。 結果は関数ライクなマクロと似ていますが、関数内で使用される識別子やマクロは、呼び出しの時点ではなく定義の時点で可視な定義を参照します。
実際にインライン化が行われたかどうかに関係なく、インライン関数に対しては以下の意味論が保証されます。
内部リンケージを持つあらゆる関数は static inline
で宣言しても構いません。
非静的インライン関数は、非 const な関数ローカル静的変数を定義することができず、ファイルスコープの静的変数を参照することができません。
staticint x;inlinevoid f(void){staticint n =1;// エラー、非静的インライン関数は非 const な静的変数を定義できません。int k = x;// エラー、非静的インライン関数は静的変数にアクセスできません。}
非静的関数を inline
宣言した場合、それは同じ翻訳単位内で定義されなければなりません。 extern
付きでないインライン定義は外部的に可視ではなく、他の翻訳単位で同じ関数を定義することを妨げません。 これにより、 inline
キーワードは、複数の翻訳単位でインクルードされるかもしれないヘッダファイル内で関数を定義するための、 static
の代替手段となります。
関数をいずれかの翻訳単位で inline
宣言する場合、それをすべての場所で inline 宣言する必要はありません。 多くとも1つの翻訳単位で、インラインでなく静的でない普通の関数または extern inline
宣言された関数も提供して構いません。 その翻訳単位は外部定義を提供すると言います。 その名前の外部リンケージを持つ関数が式で使用される場合は、プログラム内に外部定義がひとつ存在しなければなりません。 単一定義規則を参照してください。
プログラム内に外部定義が存在する場合は、その関数のアドレスは必ずその外部関数のアドレスになりますが、そのアドレスが関数呼び出しを行うために使用されたときは、インライン定義 (その翻訳単位内に存在すれば) が呼ばれるか外部定義が呼ばれるかは未規定です。 インライン定義内で定義された静的オブジェクトは、外部定義内で定義された静的オブジェクトとは異なります。
inlineconstchar*saddr(void)// このファイル内で使用するためのインライン定義。{staticconstchar name[]="saddr";return name;}int compare_name(void){return saddr()== saddr();// 未規定。 外部定義を呼ぶかもしれません。}externconstchar*saddr(void);// 外部定義も生成されます。
有効な C のプログラムは、関数のインライン版が呼ばれるか外部版が呼ばれるかに依存してはなりません。
[編集]キーワード
[編集]ノート
inline
キーワードは C++ から採用されました。 C++ では、関数をインライン宣言する場合、その関数はすべての翻訳単位でインライン宣言されなければならず、あるインライン関数のすべての定義は正確に同じでなければなりません。 C では、定義が異なっていても構いません (プログラムの動作がその差異に依存しない限り)。 非 const な関数ローカル静的変数は、 C++ では使用できますが、 C ではできません。 あるインライン関数の異なる定義内の関数ローカル静的変数は、 C++ ではすべて同じですが、 C では区別されます。
[編集]例
// ファイル test.h#ifndef TEST_H_INCLUDED#define TEST_H_INCLUDEDinlineint sum (int a, int b){return a+b;}#endif // ファイル sum.c#include "test.h"externinlineint sum (int a, int b);// 外部定義を提供します。 // ファイル test1.c#include <stdio.h>#include "test.h"externint f(void); int main(void){printf("%d\n", sum(1, 2)+ f());} // ファイル test2.c#include "test.h" int f(void){return sum(2, 3);}
出力:
8