1

inlineメンバー関数の定義をヘッダーに入れて関数をとしてマークすると、関数のコードは、関数が.cppファイルから呼び出される任意の場所にインライン化されることをすでに知っています。コンパイルされたバイナリ、関数のコードがどこにあるかを知っています-それに依存する.cppファイルのコンパイルされたコード内。しかし、ヘッダー内の関数をでマークしないとどうなりますかinline関数の本体は、コンパイラがインライン化しないことを選択できるほど大きいのでしょうか。静的/動的ライブラリのコンテキストでは、関数のクラスはどこにコンパイルされますか?関数のコードはどこにコンパイルされますか?または、まったくコンパイルされておらず、関数のコードの最終的な宛先は、ライブラリのクライアントのコンパイル済み.cppです。後者の場合、inline(コードが「重すぎる」ために)マークを付けなくても、関数のコードはインライン化されますか?そして最後に、この場合のMSVCコンパイラの動作はGCCの動作とは異なりますか?

確かに、インライン化したいメンバー関数を.hファイル(または.inlファイル)に入れ、「重い」関数を.cppファイルに入れると、物事が明確になりますが、クラスを壊さないようにしたいと思います。したがって、ファイル間での実装が重要です。

4

3 に答える 3

4

ヘッダーを含む各翻訳単位に直接コンパイルされます。そのようなファイルが複数ある場合は、1つの定義規則に違反し、プログラムの形式が正しくありません。

本当にすべてのコードを1つのファイルに入れたい場合は、それをヘッダーに入れて、関数をインラインでマークします。これは単なる提案であるため、関数が大きすぎる場合、コンパイラはそれをインライン化せず、非インライン関数とまったく同じようにコンパイルされます。ただし、コンパイル時間が大幅に増加する可能性があるため、これは標準的なC++ではないことに注意してください。通常のパターンは、実際には、インターフェース(ヘッダー)を実装(ソースファイル)から分離することです。コンパイラが関数をインライン化しないことを決定した場合、ヘッダーを含む各変換ユニットのコンパイル済みオブジェクトファイルに書き込まれ、リンカはオブジェクトファイルの1つからインスタンスを選択して、残りを破棄する必要があります(各バージョンのコードは同一であるため)。

于 2012-07-06T19:01:54.960 に答える
4

関数をマークするinlineと、呼び出されるすべての場所でコンパイラーにインライン化を強制するのではなく、定義がインラインであり、異なるコンパイル単位で重複コピーを予期する必要があることを伝えるだけです。実際のコードは、ヘッダーを含めて関数を呼び出すコンパイル単位ごとに少なくとも1回コンパイルされます。

インラインで宣言しない場合、リンカは、たとえそれらの定義が同一であっても、関数の複数の定義について文句を言う必要があります。

于 2012-07-06T19:08:29.360 に答える
2

ご存知のように、「インライン」はコンパイラへの単なる「要求」であり、それ以上のものではありません。

さらに、ヘッダーでスタンドアロンの「静的」関数を宣言することを妨げるものは何もありません。その時点で、同じバイナリコードが、ソースファイル#includeがヘッダーであるすべてのオブジェクトファイルで複製されます。

何を推測しますか-インライン関数でも同じことが起こり得ます:)

個人的には、ヘッダーファイルにクラスと構造体の定義、typedef、定数、関数プロトタイプ...そしてexterns...しか表示されないのが好きです。

于 2012-07-06T19:06:03.637 に答える