exponenta event banner

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 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

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

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