回答:
inline
実際の呼び出しを実行する代わりに、関数の内容を呼び出しコードに埋め込もうとするようコンパイラーに指示します。
頻繁に呼び出され、パフォーマンスに大きな影響を与える可能性がある小さな関数の場合。
ただし、これは単なる「ヒント」であり、コンパイラはそれを無視する可能性があり、ほとんどのコンパイラは、キーワードが使用されていない場合でも、可能な場合は最適化の一部として「インライン化」を試みます。
例えば:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
このタイトなループは各反復で関数呼び出しを実行し、関数の内容は実際には、コンパイラーが呼び出しを実行するために配置する必要があるコードよりも大幅に少なくなります。inline
基本的に、上記のコードを同等のコードに変換するようコンパイラーに指示します。
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
実際の関数呼び出しをスキップして戻る
明らかに、これは要点を示すための例であり、実際のコードではありません。
static
スコープを指します。Cでは、関数/変数は同じ変換単位内でのみ使用できます。
static
(の有無にかかわらずinline
)はヘッダーに完全に含まれている可能性があります。理由はわかりません。テンプレートは、C ++用で、この質問はC.についてです
inline
芋、良いスタイルである
inline
は、インライン化を試みるようコンパイラーに指示していません。プログラマが関数本体を複数の変換単位に含めることができるようにするだけで、ODR違反はありません。これの副作用は、関数をインライン化するときに、コンパイラが実際にこれを実行できるようにすることです。
デフォルトでは、インライン定義は現在の翻訳単位でのみ有効です。
ストレージクラスがのextern
場合、識別子には外部リンケージがあり、インライン定義も外部定義を提供します。
ストレージクラスがのstatic
場合、識別子には内部リンケージがあり、インライン定義は他の変換単位では見えません。
ストレージクラスが指定されていない場合、インライン定義は現在の翻訳単位でのみ表示されますが、識別子には引き続き外部リンケージがあり、外部定義を別の翻訳単位で提供する必要があります。現在の翻訳単位内で関数が呼び出された場合、コンパイラーはインライン定義または外部定義を自由に使用できます。
コンパイラは、現在の翻訳単位で定義を表示できる関数をインライン化できます(インライン化できません)。したがって、C標準では実際には考慮されていませんが、リンク時の最適化により、異なる翻訳単位でもそれ)、ほとんどの実際的な目的のために、static
とstatic inline
関数の定義の間に違いはありません。
inline
(のような指定register
ストレージクラス)は唯一のコンパイラヒントであり、コンパイラはそれを完全に無視して自由です。標準に準拠した非最適化コンパイラは、その副作用を尊重するだけでよく、最適化コンパイラは、明示的なヒントの有無にかかわらず、これらの最適化を行います。
inline
そしてregister
、彼らはプログラマが最適化が不可能にコードを書き込むときにエラーをスローするようにコンパイラーに指示して、けれども、役に立たないです:外部inline
内部リンケージを持つ定義ができない参照識別子(これらは異なる翻訳単位で利用できないだろうと)または、静的ストレージ期間を使用して変更可能なローカル変数を定義します(これらは変換ユニット間で状態を共有しないため)register
。また、修飾された変数のアドレスを取得することはできません。
個人的には、関数定義をヘッダーファイルに配置する主な理由はインライン化できるようにするために、この規則を使用してstatic
ヘッダー内の関数定義にもマークを付けますinline
。
一般に、ヘッダー内の宣言に加えて、static inline
関数とstatic const
オブジェクトの定義のみを使用しますextern
。
とはinline
異なるストレージクラスで関数を記述したことはありませんstatic
。
inline
インライン化に実際に適用されているかのように話す答えはすべて誤解を招き、間違いなく間違いです。最近のコンパイラは、関数のインライン化を有効にするために、インライン化またはそれを必要とするヒントとしてこれを使用していません。
GCCとの私の経験から私がいることを知っているstatic
とstatic inline
方法で、どのように異なるか未使用の関数についてコンパイラの警告を発します。より正確には、static
関数を宣言し、それが現在の翻訳単位で使用されていない場合、コンパイラーは未使用の関数に関する警告を生成しますが、に変更することでその警告を抑制することができますstatic inline
。
したがって、私はそれをstatic
翻訳単位で使用する必要があると思う傾向があり、追加のチェックコンパイラが未使用の関数を見つけるために行うメリットがあります。また、static inline
警告を出さずにインライン化できる(外部リンケージがないため)関数を提供するために、ヘッダーファイルで使用する必要があります。
残念ながら、私はその論理の証拠を見つけることができません。GCCのドキュメントからでも、それがinline
未使用の関数の警告を抑制すると結論付けることができませんでした。誰かがその説明へのリンクを共有してくれるとありがたいです。
warning: unused function 'function' [clang-diagnostic-unused-function]
ました。しかし、間違いなく、これは&を組み合わせる最高の説明と理由の1つです。static inline
clang-tidy
static
inline
Cでは、static
定義する関数または変数は、このファイル(つまり、コンパイル単位)でのみ使用できます。
したがって、static inline
このファイルでのみ使用できるインライン関数を意味します。
編集:
コンパイル単位は翻訳単位でなければなりません
the compile unit
間違って書いたものだと思います、そのようなことはありません、実際の用語はtranslation unit
言語レベルではなく、一般的な実装レベルでの1つの違い:gccの特定のバージョンでは、参照されていないstatic inline
関数がデフォルトで出力から削除されますが、static
参照されていない場合でもプレーンな関数が保持されます。これがどのバージョンに該当するかはわかりませんが、実用的な観点からは、ヘッダーの関数に常に使用することinline
をお勧めしstatic
ます。
inline
定義での使用についてはどうですか?extern
関数に使用しないことも意味しますか?
attribute((used))
、その履歴とその使用を調べて、asmが他の参照されていないstatic
関数とデータを参照できるようにすることができます。
static
スコープを指します。Cでは、関数/変数は同じ変換単位内でのみ使用できます。