CERT C: Rec. PRE06-C

Заключите заголовочные файлы в защиту включения

Описание

Управляйте определением

Заключите заголовочные файлы в защиту включения. [1]

Примеры

развернуть все

Описание

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

Если вы включаете заголовочный файл, содержимое которого не охраняют от нескольких включение, анализ повышает нарушение этой директивы. Нарушение показывают в начале заголовочного файла.

Можно охранять содержимое заголовочного файла от нескольких включение при помощи одного из следующих методов:

<start-of-file>
#ifndef <control macro>
#define <control macro>
    /* Contents of file */
#endif
<end-of-file>
или
<start-of-file>
#ifdef <control macro> 
#error ...
#else
#define <control macro>
    /* Contents of file */
#endif
<end-of-file>
Если вы не используете один из этих методов, Polyspace® отмечает включение заголовочного файла как несовместимое.

Риск

Когда модуль перевода содержит комплексную иерархию вложенных заголовочных файлов, для конкретного заголовочного файла возможно быть включенным несколько раз, ведя к беспорядку. Если это несколько, включение производит несколько или конфликтные определения, то ваша программа может иметь неопределенное или ошибочное поведение.

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

#ifdef _WIN64
   int env_var;
#elseif  
   long int env_var;
#endif
Если заголовочный файл содержится в двух путях к включению, тот, который задает макро-_WIN64 и другого, который не задает его, у вас могут быть конфликтные определения env_var.

Пример - код после макро-охраны

#ifndef  __MY_MACRO__ 
#define __MY_MACRO__
    void func(void);
#endif
void func2(void);

Если заголовочный файл содержит этот код, это несовместимо, потому что макро-защита не покрывает целое содержимое заголовочного файла. Строка void func2(void) вне защиты.

Примечание

У вас могут быть комментарии вне макро-защиты.

Пример - код перед макро-охраной

void func(void);
#ifndef  __MY_MACRO__ 
#define __MY_MACRO__
    void func2(void);
#endif

Если заголовочный файл содержит этот код, это несовместимо, потому что макро-защита не покрывает целое содержимое заголовочного файла. Строка void func(void) вне защиты.

Примечание

У вас могут быть комментарии вне макро-защиты.

Пример - не сочетается в макро-охране

#ifndef  __MY_MACRO__ 
#define __MY_MARCO__
    void func(void);
    void func2(void);
#endif

Если заголовочный файл содержит этот код, это несовместимо, потому что макро-имя в операторе #ifndef отличается от имени в следующем операторе #define.

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

Группа: Rec. 01. Препроцессор (PRE)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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