GCC を使用しているため、C99inline
関数指定子メカニズムを使用できます。これは ISO/IEC 9899:1999 からのものです。
§ 6.7.4 関数指定子
構文
¶1関数指定子:
inline
制約
¶2 関数指定子は、関数の識別子の宣言でのみ使用されます。
¶3 外部リンケージを持つ関数のインライン定義には、静的保存期間を持つ変更可能なオブジェクトの定義が含まれてはならず、内部リンケージを持つ識別子への参照が含まれてはなりません。
¶4 ホスト環境では、inline
関数指定子は の宣言に現れてはならないmain
。
セマンティクス
¶5inline
関数指定子で宣言された関数はインライン関数です。関数指定子は複数回出現する場合があります。動作は、一度だけ表示された場合と同じです。関数をインライン関数にすることは、関数の呼び出しが可能な限り高速であることを示唆しています。118)そのような提案が有効である範囲は、実装によって定義されます。119)
¶6 内部リンケージを持つ関数はすべてインライン関数にすることができます。外部リンケージを持つ関数の場合、次の制限が適用されます。関数がinline
関数指定子で宣言されている場合、同じ翻訳単位でも定義される必要があります。翻訳単位内の関数のすべてのファイル スコープ宣言にinline
なしの関数指定子が含まれている場合extern
、その翻訳単位内の定義はインライン定義です。. インライン定義は関数の外部定義を提供せず、別の翻訳単位での外部定義を禁止しません。インライン定義は、翻訳者が同じ翻訳単位内の関数への呼び出しを実装するために使用できる外部定義の代替手段を提供します。関数の呼び出しがインライン定義を使用するか、外部定義を使用するかは指定されていません。
¶7 例 外部リンケージを持つインライン関数の宣言は、外部定義、または翻訳単位内でのみ使用可能な定義のいずれかになります。を使用したファイル スコープ宣言
extern
は、外部定義を作成します。次の例は、翻訳単位全体を示しています。
inline double fahr(double t)
{
return (9.0 * t) / 5.0 + 32.0;
}
inline double cels(double t)
{
return (5.0 * (t - 32.0)) / 9.0;
}
extern double fahr(double); // creates an external definition
double convert(int is_fahr, double temp)
{
/* A translator may perform inline substitutions */
return is_fahr ? cels(temp) : fahr(temp);
}
¶8 の定義はexternでも宣言されてfahr
いるので外部定義ですが、セルの定義はインライン定義であることに注意してください。fahr
外部リンケージがあり、参照されるためcels
、外部定義は別の翻訳単位に表示される必要があります (6.9 を参照)。インライン定義と外部定義は別個のものであり、どちらも呼び出しに使用できます。
118)たとえば、「インライン置換」など、通常の関数呼び出しメカニズムの代替手段を使用する。インライン置換はテキスト置換ではなく、新しい関数も作成しません。したがって、たとえば、関数の本体内で使用されるマクロの展開では、関数が呼び出される場所ではなく、関数の本体が表示される時点での定義が使用されます。識別子は、本体が発生するスコープ内の宣言を参照します。同様に、関数は、外部定義に加えて発生するインライン定義の数に関係なく、1 つのアドレスを持ちます。
119)たとえば、実装はインライン置換をまったく実行しないか、inline
宣言のスコープ内の呼び出しに対してインライン置換のみを実行する可能性があります。
120)インライン定義は、対応する外部定義および他の翻訳単位の他の対応するインライン定義とは異なるため、静的ストレージ期間を持つすべての対応するオブジェクトも、それぞれの定義で異なります。
標準化される前に、GCC にもinline
C の関数があったことに注意してください。その表記が必要な場合は、詳細について GCC マニュアルを参照してください。