関数の前に inline キーワードを使用することと、ヘッダーで関数全体を宣言することの違いは何ですか?
それで...
int whatever() { return 4; }
対
.h:
inline int whatever();
.cpp:
inline int myClass::whatever()
{
return 4;
}
さらに言えば、これは何をしますか:
inline int whatever() { return 4; }
関数の前に inline キーワードを使用することと、ヘッダーで関数全体を宣言することの違いは何ですか?
それで...
int whatever() { return 4; }
対
.h:
inline int whatever();
.cpp:
inline int myClass::whatever()
{
return 4;
}
さらに言えば、これは何をしますか:
inline int whatever() { return 4; }
いくつかの側面があります。
言語
inline
キーワードでマークされている場合、その定義は TU で使用可能である必要があります。そうでない場合、プログラムの形式が正しくありません。inline
ます。inline
、(ODR を考慮して) 複数の TU で定義される場合がありますが、通常の関数の場合はそうではありません。inline
ます。コンパイラの動作
inline
は、必要に応じて各オブジェクト ファイルの弱いシンボルとして発行されます。これにより、サイズが大きくなる可能性があります (テンプレートの肥大化を調べてください)。リンカーの動作
の目的はinline
、関数を複数の翻訳単位で定義できるようにすることです。これは、一部のコンパイラが関数が使用される場所にインライン化できるようにするために必要です。テンプレートやクラス定義内の関数を定義するときは省略できますが、ヘッダー ファイルで関数を定義するときは常に使用する必要があります。
ヘッダーなしで定義するのinline
は非常に悪い考えです。複数の翻訳単位のヘッダーを含めると、1 つの定義ルールが破られます。あなたのコードはおそらくリンクせず、リンクした場合に未定義の動作を示す可能性があります。
ヘッダーで宣言するinline
が、ソースファイルで定義することも非常に悪い考えです。定義は、それを使用するすべての翻訳単位で使用できる必要がありますが、ソース ファイルで定義することにより、1 つの翻訳単位でのみ使用できます。別のソース ファイルにヘッダーが含まれていて関数を呼び出そうとすると、プログラムは無効になります。
がないと 、関数が名前空間またはグローバル スコープで宣言されている場合に、inline
複数のエクスポートされたシンボルが作成される可能性があります(リンカー エラーが発生します)。
ただし、クラスの場合(例に見られるように)、ほとんどのコンパイラは暗黙的にメソッドをインラインとして宣言します(-fno-default-inline
GCCでそのデフォルトを無効にします)。
関数をインラインとして宣言すると、コンパイラはその定義を翻訳で確認することを期待する場合があります。したがって、定義が表示される時間のために予約する必要があります。
より高いレベル: クラス宣言の定義は、多くの場合、より多くの翻訳に表示されます。これにより最適化が向上し、コンパイル時間が長くなる可能性があります。
手作業による最適化と高速コンパイルの両方が重要でない限り、最近ではクラス宣言でキーワードを使用することは珍しくありません。
この質問は、インライン関数について多くを説明しています __inline__ とはどういう意味ですか? (インラインキーワードについてでしたが。)
基本的にヘッダーとは関係ありません。ヘッダーで関数全体を宣言すると、関数のソースが含まれるソース ファイルが変更されるだけです。インライン キーワードは、結果としてコンパイルされた関数が配置される場所を変更します。すべての呼び出しの (パフォーマンスの向上)。ただし、コンパイラは、インラインにする関数またはメソッドを自分で選択する場合があり、キーワードは単にコンパイラへの提案です。インラインで指定されていない関数でも、パフォーマンスが向上する場合は、インラインになるようにコンパイラによって選択できます。
複数のオブジェクトを実行可能ファイルにリンクしている場合、通常、関数の定義を含むオブジェクトは 1 つだけです。For int whatever() { return 4; }
- オブジェクトを生成するために使用される翻訳単位には、関数の定義 (実行可能コード) が含まれwhatever
ます。リンカーは、呼び出し元をどちらに転送するかを知りません。が指定されている場合inline
、実行可能コードは呼び出しサイトでインライン化される場合とされない場合がありますが、インライン化されていない場合、リンカはすべての定義が同じであると想定し、任意に 1 つを選択して呼び出し元を誘導することができます。どういうわけか定義が同じでない場合、それはあなたのせいと見なされ、未定義の動作が発生します。使用するにはinline
、呼び出しをコンパイルするときに定義を知る必要があるため、インライン宣言をヘッダーに入れ、インライン定義を.cppファイルに入れるという考えは、すべての呼び出し元がたまたま同じ.cppファイルの後半にある場合にのみ機能します。一般的には壊れており、(名目上) インライン関数の定義が、それを宣言するヘッダーに表示されることを期待します (または、事前に宣言されていない単一の定義があることを期待します)。