10

コード例を次に示します。

enum Foo // or enum class whatever
{   BAR
,   STUFF
};

inline const char* to_string( const Foo& foo )
{
    static const char* const NAMES[] = 
    {    "BAR"
    ,    "STUFF"
    };
    // let's assume I have some boundary checks here, it's not the point
    return NAMES[foo];
};

この関数はインラインで、いくつかのコンパイル ユニットで使用されるヘッダーにあります。ここでの目標は、この関数が使用されない場合、コンパイラが何もしないようにすることです。

質問:

  1. C++ 標準は、NAMES が 1 つのオブジェクト ファイルにのみ存在することを保証しますか?それとも、すべてのオブジェクト ファイルにそのコピーがあることを決定するのはコンパイラに任されていますか?
  2. 複数のコピーがある場合、それはリンクの問題になりますか (それを確認するのに十分なコンパイラをテストできないと思います)。
  3. gcc、msvc、clang はすべて、最終的なバイナリに NAMES のインスタンスを 1 つだけ持たせることで、このケースを最適化しますか?
4

2 に答える 2

7

はい、標準ではオブジェクトが1つだけになることが保証されています。C++03§7.1.2/4から:

[...]関数static 内のローカル変数は、extern inline常に同じオブジェクトを参照します。externインライン関数の文字列リテラルは、異なる変換単位の同じオブジェクトです。

extern inline(関数はinline外部リンケージを持つinline関数、つまり。としてマークされていない関数であることに注意してくださいstatic。)

どのオブジェクトファイルに表示されるかはコンパイラによって異なりますが、それを使用する各オブジェクトファイルがコピーを取得し、リンカが任意にシンボルの1つを選択し、残りを破棄するのではないかと思います。

于 2012-11-08T23:46:41.363 に答える
1

標準では、1つのコピーのみが使用されることが保証されています。コード内のスペースを占める未使用のコピーがないことを保証するものではありません。

リンカは通常、同じインスタンスを使用するためにすべての参照を統合する責任があります。

于 2012-11-08T23:41:12.827 に答える