無名名前空間とは何か
外部から読み取れない
無名名前空間内で宣言されたシンボルは一見グローバル空間に定義されているように見える。
しかし、実際には他のファイル・コンパイラからは実体を読み取れず、ローカルなものとなる。
これは、もし他のファイルで同名のシンボルがあったとしても、One Definition Ruleの侵害にあたらないこととなる。
A.cpp
namespace{ int a = 0; } int b = 8;
B.cpp
#include "A.hpp" int main(){ extern int a; //ERROR extern int b; printf("%a, %b",a, b); }
A.cppのint aは外部リンケージを持たないため外部結合できない。
int bは外部リンケージをもつ.
リンケージ (linkage)とは
ソースコードが複数ある場合にはリンケージという概念が登場します。関数およびグローバル変数が有する属性で、ファイルを越えて利用できるかどうかを示す性質です。実体が定義されたファイルの外で利用できる関数やグローバル変数を「外部 (external) リンケージをもつ」と表現します。逆に、実体が定義されたファイルの中でのみ利用できる関数やグローバル変数を「内部 (internal) リンケージをもつ」と表現します。
https://www.qoosky.io/techs/719b1e5927
例えば,グローバル変数は外部リンケージをもつ.
staticをつけると内部リンケージをもつようになる.
外部リンケージを持つ関数やグローバル変数を利用するためにはexternを使う.
名前衝突の回避
無名名前空間で宣言したシンボルも名前衝突の原因になることがある。
このときは::修飾子による名前解決が必要。
staticより優先的に使うべき
上記のように無名名前空間は,変数などに外部リンケージをもたせず,staticと同じ働きをする.
staticと比べて優先的に使うべきな理由として下記がある.
- namespaceは関数や変数だけでなく全てに対応できるため.
- staticは多くの使い方がありすぎる.
(参考)
http://stackoverflow.com/questions/4977252/why-unnamed-namespace-is-a-superior-alternative-to-static