3

C ++で名前空間を使用して関数を定義し、それらが定義されているコンパイルユニットの外部から呼び出せないようにすることは、シンボルテーブルが大きくなるため、非常に大規模なコード環境では適切ではないと主張していると聞きました。名前のない場合にC++コンパイラが提供する自動生成された名前空間にこれらのシンボルへのエントリを含めることにより、不必要に大きくなります。

namespace {
  // This function can only be accessed from hear to the end of 
  // any compilation unit that includes it.
  void functionPerhapsInsertedIntoSymbolTable() {
    return;
  }
}

これはおそらく、上記が次のことを行うのと同じであると想定されていることを前提としています。

namespace randomlyGenerateNameHereNotCollidingWithAnyExistingNames {
  // This function can only be accessed from hear to the end of
  // any compilation unit that includes it.
  void functionPerhapsInsertedIntoSymbolTable() {
    return;
  }
}
using randomlyGenerateNameHereNotCollidingWithAnyExistingNames;

しかし、それは本当に簡単ですか?コンパイラは、生成された名前空間名のシンボルのシンボルテーブルエントリを作成する必要がありますか?

代わりに、そのような状況では、静的宣言を使用することが提案されていると聞きました。

// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
static void functionNotInsertedIntoSymbolTable() {
  return;
}

名前のない名前空間に配置する代わりに関数の前に静的宣言を使用すると、関数が定義されているコンパイル単位の外部で関数にアクセスできなくなるのと同じ効果がありますか?シンボルテーブルを大きくしない可能性があることを除いて、これら2つのアプローチの間に違いはありますか?

名前のない名前空間によるシンボルテーブルの肥大化の問題は、C ++の一部の実装のバグにすぎないのでしょうか、それとも、コンパイラがそのような関数のエントリを作成するために標準で何らかの形で必要とされているのでしょうか。この膨張がバグと見なされる場合、これが問題にならない既知のコンパイラはありますか?

4

2 に答える 2

4

名前のない名前空間に配置する代わりに関数の前に静的宣言を使用すると、関数が定義されているコンパイル単位の外部で関数にアクセスできなくなるのと同じ効果がありますか?

はい。

Namespace-は、名前のない名前空間を優先してC ++ 03でstatic推奨になりましたが、実際には、C ++ 11はまったく同じものであり、非推奨の目的がないことに誰もが気付いたため、非推奨ではありませんでした。

これら2つのアプローチに違いはありますか

いいえ、そうではありません。名前空間を使用しているため、名前の検索に微妙な点があるかもしれませんが、現時点では考えられません。

シンボルテーブルを成長させない可能性がある以外は?

これはlanguage-lawyer解決すべき明確な実用上の問題がない質問であるため、C ++言語にはシンボルテーブルの概念がなく、したがってこの効果を示すものがないことを指摘する必要があります。

また、名前空間に名前のない名前空間が何万もあるまで、目立った影響はありません。あなたは?

于 2013-01-17T18:20:07.807 に答える
0

名前空間の名前空間と名前空間レベルの静的な非推奨の理由は、不運なexportキーワードです。

エクスポートされたテンプレートが依存するものはすべて、インスタンス化の時点でリンクアクセス可能である必要があります。これは、さまざまなソースファイルにある可能性があります。名前のない名前空間は、エクスポートされたテンプレートのリンクを維持しながら、静的な「民営化」の側面を可能にしました。

C ++ 2011でエクスポートが削除されたので、名前空間の名前空間の外部リンケージ要件が削除され、名前空間レベルの静的とまったく同じように動作するようになりました。標準に精通している人は、これを確認/反論することができます。

于 2013-01-17T18:38:49.653 に答える