次のコードに違いはありますか。
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
両方の関数がインライン化されますか? インラインは実際に違いがありますか?コードをインライン化する必要がある場合とすべきでない場合のルールはありますか? 構文 (アクセサなど)をよく使用しますが、直接AnotherFunc
指定することはめったにありません。inline
次のコードに違いはありますか。
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
両方の関数がインライン化されますか? インラインは実際に違いがありますか?コードをインライン化する必要がある場合とすべきでない場合のルールはありますか? 構文 (アクセサなど)をよく使用しますが、直接AnotherFunc
指定することはめったにありません。inline
キーワードは、本質的にコンパイラへのinline
ヒントです。を使用inline
しても、関数がインライン化されることは保証されません。また、省略しても、関数がインライン化されないことが保証されません。その特定の関数をインライン化するためにもっと努力するのが良い考えかもしれないことをコンパイラに知らせているだけです。
どちらのフォームもまったく同じ方法でインライン化する必要があります。Inline は、クラス定義で定義された関数本体に対して暗黙的です。
Sutter's Guru of the Week #33 が、あなたの質問などに答えます。
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
どちらの方法でも同じようにコンパイルされることが保証されているのは正しいことです。ただし、これらの方法のいずれも行わないことが望ましいです。C++ FAQによると、通常はクラス定義内で宣言してから、明示的なinlineキーワードを使用して、クラス定義の外、ヘッダー内で定義する必要があります。これは、FAQ に記載されているように、他の人が読みやすいように宣言と定義を分離したいためです (宣言は「何を」と定義は「どのように」に相当します)。
インラインは実際に違いがありますか?
はい、コンパイラがインライン要求を許可する場合、それは大きく異なります。インライン コードをマクロと考えてください。関数呼び出しは、呼び出されるすべての場所で、関数定義内の実際のコードに置き換えられます。これにより、大きな関数をインライン化するとコードが肥大化する可能性がありますが、関数が大きすぎる場合、コンパイラは通常、インライン要求を許可しないことでこれを防ぎます。
コードをインライン化する必要がある場合とすべきでない場合のルールはありますか?
厳密なルールと高速なルールについては知りませんが、ガイドラインは、頻繁に呼び出され、比較的小さい場合にのみインライン コードにすることです。セッターとゲッターは一般的にインライン化されています。コードの特にパフォーマンスが集中する領域にある場合は、インライン化を検討する必要があります。インライン化では、実行速度と実行可能サイズを交換していることを常に覚えておいてください。
コンパイラよりも詳しいと思われる場合、 VC++ は__forceinlineおよび__declspec(noinline)ディレクティブをサポートします。ヒント: あなたはおそらくそうではないでしょう!
Inline はコンパイラのヒントであり、コンパイラにコードのインライン化を強制しません (少なくとも C++ では)。したがって、短い答えは、コンパイラであり、おそらくコンテキストに依存して、例で何が起こるかです。ほとんどの優れたコンパイラは、特に両方の関数からの定数戻り値が明らかに最適化されているため、おそらく両方をインライン化します。
一般に、インラインは気にする必要はありません。これにより、マシン命令を実行してスタック フレームを生成し、制御フローを返す必要がないというパフォーマンス上の利点がもたらされます。しかし、最も特殊なケースを除いて、それは取るに足らないことだと私は主張します。
インラインは 2 つの場合に重要です。リアルタイム環境にいて、十分に速く応答しない場合に 1 つ。2 つは、コード プロファイリングが非常にタイトなループ (つまり、サブルーチンが何度も呼び出される) で重大なボトルネックを示した場合、インライン化が役立つ可能性があることです。
特定のアプリケーションやアーキテクチャによっては、最適化としてインライン化が必要になる場合もあります。
一部のC++コンパイラ(つまりSunStudio)は、インラインが次のように省略されていると文句を言うことがわかりました。
int AnotherFunc() { return 42; }
したがって、この場合は常にinlineキーワードを使用することをお勧めします。また、後で実際の関数呼び出しとしてメソッドを実装する場合は、インラインキーワードを削除することを忘れないでください。これにより、リンクが実際に混乱します(SunStudio11および12とBorlandC ++ Builderの場合)。デバッガーを使用してコードをステップスルーすると、「ステップオーバー」コマンドを使用している場合でもインラインコードに「ステップイン」するため、インラインコードの使用を最小限に抑えることをお勧めします。これはかなり煩わしい場合があります。
クラスの外では、コードでより便利なことを行うことに注意してくださいinline
。C++コンパイラに、関数を呼び出すたびにインラインでコードを生成させることで、同じシンボル(関数シグネチャ)の複数の定義を防ぎます。 )異なる翻訳単位で。
したがって、非メンバー関数をヘッダーファイルにインライン化し、それを複数のcppファイルにインクルードすると、リンカーが怒鳴ることはありません。関数が大きすぎてインライン化を提案できない場合は、Cの方法で実行します。ヘッダーで宣言し、cppで定義します。
これは、コードが実際にインライン化されているかどうかとはほとんど関係ありません。短いメンバー関数で一般的なように、ヘッダーでの実装スタイルが可能になります。
(テンプレート関数の場合のように、関数の非インラインレンダリングが必要な場合、コンパイラは賢くなると思いますが...)
また、グレッグが言ったことに加えて、最適化 (つまりinline
-ing) を実行するとき、コンパイラーはコード内のキーワードだけでなく、コンパイラーがコードを最適化する方法を指定する他のコマンドライン引数も参照します。