Unnamed namespace in header file

Заголовочный файл содержит неназванное пространство имен, ведущее к нескольким определениям

Описание

Этот дефект возникает, когда в заголовочном файле используется неназванное пространство имен, что может привести к нескольким определениям объектов в пространстве имен.

Риск

Согласно стандарту C++, имена в неназванном пространстве имен, например aVar:

namespace {
   int aVar;
}
иметь внутреннее редактирование по умолчанию. Если заголовочный файл содержит неназванное пространство имен, то каждый модуль преобразования с исходным файлом, который #include-s заголовочный файл задает свой собственный образец объектов в пространстве имен. Многочисленные определения, вероятно, не те, что вы планировали, и могут привести к неожиданным результатам, нежелательному избыточному использованию памяти или непреднамеренному нарушению правила с одним определением.

Зафиксировать

Задайте имена для пространств имен в файлах заголовков или избегайте использования пространств имен в файлах заголовков.

Примеры

расширить все

Заголовок файла: aHeader.h

namespace {
   int aVar;
}

Первый исходный файл: 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;
}

Второй исходный файл: 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 в модуле перевода из aSource.cpp и модуль перевода из anotherSource.cpp. Эти два определения приводят к возможному неожиданному выходу:

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

Коррекция - Избегайте неназванного пространства имен

Одна из возможных коррекций состоит в том, чтобы избежать пространства имен в заголовочном файле.

Заголовок файла: aHeader.h

extern int aVar;

Первый исходный файл: 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;
}

Второй исходный файл: 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++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : UNNAMED_NAMESPACE_IN_HEADER
Влияние: Средний
Введенный в R2019b