12

inline キーワードを使用したり、クラス宣言にメソッドを挿入したり、短い ctor または getter メソッドを使用したりできることは理解していますが、メソッドをいつインライン化するかについて最終的な決定を下すのはコンパイラですか?

例えば:

inline void Foo::vLongBar()
{
   //several function calls and lines of code
}

コードが非効率になるとコンパイラが判断した場合、コンパイラはインライン宣言を無視しますか?

副次的な問題として、次のようにクラス外で宣言された getter メソッドがある場合:

void Foo::bar() { std::cout << "baz"; }

コンパイラはこれを裏でインライン化しますか?

4

9 に答える 9

15

はい、コードをインライン化するかどうかの最終決定は、C++ コンパイラにあります。inline キーワードは提案であり、要件ではありません。

この決定が Microsoft C++ コンパイラでどのように処理されるかについての詳細を次に示します。

于 2009-07-30T07:30:24.370 に答える
12

関数がインライン化されるかどうかは、結局のところ、完全にコンパイラ次第です。通常、フローに関して関数が複雑になるほど、コンパイラが関数をインライン化する可能性は低くなります。また、再帰関数などの一部の関数は、単純にインライン化できません。

関数をインライン化しない主な理由は、コード全体のサイズが大幅に増加し、iot がプロセッサのキャッシュに保持されなくなるためです。これは実際には、最適化ではなく悲観化です。

プログラマーが自分の足や他の場所で自分自身を撃つことを決定できるようにするために、関数を自分でインライン化できます。関数の呼び出しサイトであったはずの関数に入るコードを記述します。

于 2009-07-30T07:30:43.150 に答える
4

他の人が指摘しているように、inlineキーワードは、コードをインライン化するためのコンパイラへの単なる提案です。コンパイラは、でマークされていないコードを定期的にインライン化し、マークされているインラインコードではないため、キーワードはor(pre-C ++ 0x)inlineと同じくらい冗長に見えます。registerauto

ただし、inlineキーワードが影響するもう1つのことがあります。それは、関数のリンクを外部(関数のデフォルト)からインラインに変更します。インラインリンケージを使用すると、各コンパイルユニットにオブジェクトコードの独自のコピーを含めることができ、リンカは最終的な実行可能ファイルから冗長なコピーを削除します。それがテンプレートを思い出させるなら、はい、テンプレートもインラインリンケージを使用します。

于 2009-07-30T08:53:21.813 に答える
4

多くの人がすでに投稿しているように、forceinline などの確固たるヒントを与えることができたとしても、最終的な決定は常にコンパイラ次第です。
理論的根拠の一部は、インライン化が自動的な「高速化」スイッチではないということです。インライン化が多すぎると、コードが非常に大きくなり、他の最適化に干渉する可能性があります。インライン関数とパフォーマンスについては、The C++ FAQ Liteを参照してください。

于 2009-07-30T07:49:43.097 に答える
3

私の5セントを追加するだけです...

インライン化に関するこのGuruofWeekの記事は非常に便利でした。

私が覚えている限り、リンカーでさえオブジェクトファイルをリンクし、リンクされているコードをインライン化できることがわかったときに、リンカーでさえインライン化を行う可能性があることをどこかで読みました。

于 2009-07-30T14:31:16.980 に答える
3

はい、コンパイラが最終決定を下します。VS では、再帰関数を指定された深さにインライン化することもできます;)

#pragma inline_depth( [0... 255] )
于 2009-07-30T07:37:40.127 に答える
2

副次的な問題として、次のようにクラス外で宣言された getter メソッドがある場合:

void Foo::bar() { std::cout << "baz"; }

コンパイラはこれを裏でインライン化しますか?

場合によります。同じ翻訳単位 (.cppファイルとその #include 定義のすべて) 内のすべての呼び出し元に対して可能です。ただし、翻訳単位の外にその関数の呼び出し元が存在する可能性があるため、インライン化されていないバージョンをコンパイルする必要があります。これは、高い最適化レベルで動作している可能性があります (コンパイラが実際に実行できる場合)。(特に: すべての .cpp ファイルを 1 つの .cpp に #include した場合と典型的なレイアウトの場合を比較してください。すべての定義が 1 つの翻訳単位にあると、そのようなインライン化の機会が劇的に増加します。)

于 2009-07-30T07:53:39.890 に答える
1

本当に、積極的に、絶対に、必ずコードをインライン化する必要がある場合は、常にマクロがあります。Cはこれらを何年にもわたってサポートしてきましたが、コンパイル前の単なるテキスト置換であるため、実際には、あなたが書いたものは何でもインラインになります。

そのため、「インライン」キーワード(場合によっては強制バリアント)には、それを強制する標準的な方法がない余裕があります。いつでもマクロを作成できます。

とは言うものの、inlineキーワードの方が優れていることがよくあります。これは、コンパイラーが関数をインライン化することが理にかなっているかどうかをよく知っており、inlineが残りのコンパイラー最適化と相互作用できるためです。

于 2009-07-30T14:38:15.830 に答える
1

私の知る限り、コンパイラは、for や while などのループが見つかった場合、インラインで宣言した (またはクラス宣言内に記述した) 関数を自動的に非インラインにします。これは、コンパイラがインライン関数で最後の発言権を持つ 1 つの例です。

于 2009-07-30T07:31:22.213 に答える