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