web-dev-qa-db-ja.com

インライン関数と静的インライン関数の違い

誰かがインライン関数と静的インライン関数の違いを教えてもらえますか?

インラインよりも静的インラインを優先する必要があるのはどの場合ですか?

リンク中にコンパイルの問題に直面しているインライン関数があるので、この質問をしています(relocation error:... symbol has been discarded with discarded section ...)。私はそれを通常の機能にして、それはうまくいきました。今私の先輩の何人かは静的インラインで試してみると私に言った。以下は私の機能です:

inline void wizSendNotifier (const char* nn_name, bpDU* arg=0, int aspect = -1)
{
   wizuiNotifier* notifier = ::wizNtrKit.getNotifier (nn_name);
   notifier->notify (arg, aspect);
}

これはクラス内ではありません。これはヘッダーファイル内にあります!

静的関数の呼び出しは、特定のTUが定義されている場所でのみ行う必要があると思います。

私の関数はヘッダーファイルにあり、それを静的にすると、そのヘッダーファイルを含めると、静的関数がその変換単位で使用できるようになりますか?

28
Vijay

非静的inline関数宣言は、それを使用するすべての変換単位(ソースファイル)で同じ関数を参照します。

One Definition Ruleでは、関数定義の本体がすべてのTUを含む)で同一であり、長い定義が「同一」である必要があります。これは通常、すべてのソースファイルが使用する場合に満たされます。同じヘッダー、および関数が内部リンケージ(static関数を含む)を持つグローバル名、または異なるTUで異なる方法で定義されたマクロを使用しない場合。

以前に特定のリンカーエラーが発生したことを覚えていませんが、少なくともこれらの制限の1つが原因である可能性があります。要件を満たすのはあなたの責任です。そうでない場合、診断を必要としない未定義の動作です。

static inline関数宣言は、翻訳ユニットごとに異なる関数を参照しているため、たまたま同じ名前になっています。異なるTUで異なるstaticグローバル名またはマクロを使用できます。その場合、ヘッダーファイルでの定義は「同じ」に見えますが、関数が異なるTUで異なる動作をする場合があります。

この違いにより、関数にstaticローカル変数が含まれている場合、staticであるかどうかに応じて動作が異なります。 staticの場合、各TUには独自のバージョンの関数があるため、独自のstaticローカル変数のコピーがあります。もしinlineのみ、すべてのTUで使用されるstaticローカル変数のコピーは1つだけです。

41
Steve Jessop