C++ では、明示的に宣言inline
されている (またはヘッダー ファイルで定義されている) 場合にのみメソッドがインライン化されますか?
11 に答える
inlineキーワードは、同じ関数の複数の同一定義がエラーではないことをリンカに伝える (またはリンカに伝えるようにコンパイラに伝える) だけです。ヘッダーで関数を定義する場合に必要になります。または、ヘッダーが複数のコンパイル ユニットに含まれている場合、リンカーから「複数定義」エラーが発生します。
キーワードとしてinlineを選択する理由は、ヘッダーで (非テンプレートの) 関数を定義したい唯一の理由は、コンパイラによってインライン化できるようにするためであると思われます。完全な定義がない限り、コンパイラは関数呼び出しをインライン化できません。関数がヘッダーで定義されていない場合、コンパイラには宣言しかなく、関数をインライン化したくてもインライン化できません。
最近では、コードを最適化するのはコンパイラだけでなく、リンカーも同様に実行できると聞いています。関数が同じコンパイル単位で定義されていない場合でも、リンカーは関数呼び出しをインライン化できます (まだ実行していない場合)。
また、ヘッダーの 1 行よりも大きな関数を定義することは、おそらく良い考えではありません (コンパイル時間に悪影響を及ぼし、大きな関数をインライン化すると、肥大化してパフォーマンスが低下する可能性があります)。
はい、明示的に宣言されていなくても、コンパイラはコードをインライン化できますinline
。
基本的に、セマンティクスが変更されない限り、コンパイラは生成されたコードに対して事実上何でも実行できます。標準は、生成されたコードに特別なことを強制しません。
コンパイラは、関数をインライン化する場合とインライン化しない場合があります。この決定のヒントとして装飾を使用することは許可されinline
ていますが、無視することも許可されています。
inline
また、クラス定義で定義されている場合、クラス メンバー関数には暗黙的な装飾があることに注意してください。
私が間違っていなければ、最適化がオンになっていると、コンパイラは適切なルーチンまたはメソッドをインライン化します。
コンパイラはインライン宣言を無視する場合があります。これは基本的に、コンパイラがそうするかどうかを決定するためのヒントとして使用されます。コンパイラは、インラインとマークされているものをインライン化する義務も、そうでないものをインライン化しない義務もありません。基本的に、コンパイラと選択した最適化レベルに左右されます。
IBMインフォメーション・センターからのテキスト、
インライン指定子の使用は、インライン展開を実行できることをコンパイラに示唆するだけです。コンパイラは提案を自由に無視できます。
C 言語main を除くすべての関数は、インライン関数指定子を使用してインラインとして宣言または定義できます。インライン関数の本体内で静的ローカル変数を定義することはできません。
クラス宣言内に実装されたC++関数は、インラインで自動的に定義されます。クラス宣言の外で宣言された通常の C++ 関数およびメンバー関数は、main を除いて、インライン関数指定子を使用してインラインとして宣言または定義できます。インライン関数の本体内で定義された静的ローカルと文字列リテラルは、翻訳単位全体で同じオブジェクトとして扱われます。
実装に依存するため、コンパイラのドキュメントに記載されているはずです。たとえば、GCC のマニュアルによると、最適化が適用されない限り、コードをインライン化することはありません。
コンパイラがコードをインライン化しない場合、inlineキーワードはstaticと同じ効果があり、コードを呼び出す各コンパイル単位には独自のコピーがあります。スマート リンカーは、これらを 1 つのコピーに減らすことができます。
インライン化がコードのセマンティクスに違反せず、関数コードに到達できる場合、コンパイラは必要なものをインライン化できます。また、選択的にインライン化することもできます。良いアイデアだと感じた場合はインライン化し、そうでない場合やコードのセマンティクスに違反する場合はインライン化しません。
一部のコンパイラは、関数が別の翻訳単位にある場合でもインライン化を実行できます。これは、リンク時コード生成と呼ばれます。
インライン化がコードのセマンティクスに違反する典型的なケースは、仮想呼び出しと、関数アドレスを別の関数に渡すか、それを格納することです。
反対の仕様を指定しない限り、コンパイラは彼が望むように最適化します。
inline キーワードは、コンパイラへの単なる要求です。コンパイラは、関数をインラインにするかどうかを決定する権利を留保します。コンパイラの決定を後押しする主な要因の 1 つは、コードの単純さです (ループが多くない)。
メンバ関数はデフォルトでインライン宣言されます。(コンパイラはここでも決定します)
これらは厳格なルールではありません。コンパイラの実装によって異なります。
関連する他の要因を誰かが知っている場合は、投稿してください。