CERT C++: DCL59-CPP

Не задайте неназванное пространство имен в заголовочном файле

Описание

Определение правила

Не задайте неназванное пространство имен в заголовочном файле.[1]

Реализация Polyspace

Эта проверка проверяет неназванное пространство имен в заголовочном файле.

Примеры

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

Проблема

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

Риск

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

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

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

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

Пример - Неожиданные результаты из неназванных пространств имен в файлах заголовков

Заголовок файла: 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

Проверяйте информацию

Группа: 01. Объявления и инициализация (DCL)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.