28

C++ 標準は、関数への 2 つのポインターが常に等しいことを保証しますか? これは通常、非インライン関数に当てはまることを理解しています。しかし、インライン関数があり、関数へのポインターが 2 つの別々のコンパイル単位で作成される場合、リンカーは 2 つのインスタンス化をマージしますか、それとも重複した関数を発行することを許可しますか?

上記の答えが「等しい」の場合: インライン関数を含む共通のヘッダーがあり、メイン プログラムと動的に読み込まれたプラグイン (共有オブジェクト/DLL) の両方が関数へのポインターを作成する場合、これは依然として有効ですか? ?

4

2 に答える 2

27

C++11 標準のセクション §5.10/1 には次のように記載されています。

同じ型の 2 つのポインターは、両方が null であるか、両方が同じ関数を指しているか、または両方が同じアドレスを表している場合にのみ、等しいと見なされます。

同じ関数の 2 つのコピーは、同じinline関数のままです。実装の観点から、コンパイラは各翻訳単位で関数のコピーを生成しますが、リンカーはコピーの 1 つを破棄するため、1 つだけが残ります。

inline関数のアドレスを取得することで、関数がインライン化されるのを防ぎます ( 1 つの定義規則の違反を回避することが重要な とは異なります)。

DLL は標準の範囲外ですが、関数の 1 つのコピーのみがバイナリ イメージに残るため、DLL から関数アドレス (例: GetProcAddress) を取得すると、DLL 内のコードと同じ関数ポインタが取得されます。

于 2013-10-02T09:53:52.990 に答える
8

C++ 標準は、関数への 2 つのポインターが常に等しいことを保証しますか?

はい、同じ関数を指す 2 つのポインターは同等です。

これは、インライン関数を含む共通のヘッダーがあり、メイン プログラムと動的に読み込まれたプラグイン (共有オブジェクト/DLL) の両方が関数へのポインターを作成する場合でも有効ですか?

はい、7.1.2.p4 に従って

外部リンケージを持つインライン関数は、すべての翻訳単位で同じアドレスを持つ必要があります。

于 2013-10-02T10:02:06.790 に答える