メインコンテンツ

ヘッダー ファイルの無名の名前空間

複数の定義につながる無名の名前空間がヘッダー ファイルに含まれる

説明

この欠陥は、ヘッダー ファイルで無名の名前空間が使用された場合に発生します。これは、名前空間内での複数のオブジェクト定義につながる可能性があります。

リスク

C++ 規格によると、無名の名前空間内の名前 (たとえば、次の aVar) は、

namespace {
   int aVar;
}
既定では内部リンクをもちます。ヘッダー ファイルが無名の名前空間を含む場合、ヘッダー ファイルを #include しているソース ファイルをもつ各翻訳単位が、その名前空間内の自身のオブジェクト インスタンスを定義します。通常、オブジェクトを意図的に複数定義することはないため、メモリの過剰使用、単一定義ルールの違反など、予期しない結果を引き起こす可能性があります。

修正方法

ヘッダー ファイルの名前空間に名前を指定するか、ヘッダー ファイルの名前空間を使わないようにします。

すべて展開する

ヘッダー ファイル: aHeader.h

namespace {
   int aVar;
}

1 つ目のソース ファイル: aSource.cpp

#include "aHeader.h"
#include <iostream>

void setVar(int arg) {
    std::cout << "Current value: " << aVar << std::endl;
    aVar = arg;
    std::cout << "Value set at: " << aVar << std::endl;
}

2 つ目のソース ファイル: anotherSource.cpp

#include "aHeader.h"
#include <iostream>

extern void setVar(int);

void resetVar() {
    std::cout << "Current value: " << aVar << std::endl;
    aVar = 0;
    std::cout << "Value set at: 0" << std::endl;
}

void main() {
    setVar(1);
    resetVar();
}

この例では、名前空間に名前がないことによって、aVar の定義が 2 つ、aSource.cpp の翻訳単位内と、anotherSource.cpp の翻訳単位内に存在することになります。2 重の定義により、次のような予期しない出力となる可能性があります。

Current value: 0
Value set at: 1
Current value: 0
Value set at: 0

修正 – 名前空間が無名にならないようにする

1 つの修正方法として、ヘッダー ファイルでの名前空間の使用を避けます。

ヘッダー ファイル: aHeader.h

extern int aVar;

1 つ目のソース ファイル: aSource.cpp

#include "aHeader.h"
#include <iostream>

void setVar(int arg) {
    std::cout << "Current value: " << aVar << std::endl;
    aVar = arg;
    std::cout << "Value set at: " << aVar << std::endl;
}

2 つ目のソース ファイル: anotherSource.cpp

#include "aHeader.h"
#include <iostream>

extern void setVar(int);
int aVar;

void resetVar() {
    std::cout << "Current value: " << aVar << std::endl;
    aVar = 0;
    std::cout << "Value set at: 0" << std::endl;
}

void main() {
    setVar(1);
    resetVar();
}

期待どおりのシーケンスが出力に表示されます。

Current value: 0
Value set at: 1
Current value: 1
Value set at: 0

結果情報

グループ: プログラミング
言語: C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: UNNAMED_NAMESPACE_IN_HEADER
影響度: Medium

バージョン履歴

R2019b で導入