exponenta event banner

CERT C++: MSC38-C

Не обрабатывайте предопределенный идентификатор как объект, если он может быть реализован только как макрос

Описание

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

Не обрабатывайте предопределенный идентификатор как объект, если он может быть реализован только как макрос. [1 ]

Внедрение Polyspace

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

Примеры

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

Проблема

Предопределенный макрос, используемый в качестве объекта, возникает при использовании определенных идентификаторов способом, требующим наличия базового объекта. Эти идентификаторы определяются как макросы. Стандарт C не позволяет переопределять их как объекты. Идентификаторы используются таким образом, что макро-расширение идентификаторов невозможно.

Например, имеется ссылка на внешнюю переменную. errno:

extern int errno;
Однако errno встречается не как переменная, а как макрос.

Дефект относится к следующим макросам: assert, errno, math_errhandling, setjmp, va_arg, va_copy, va_end, и va_start. Средство проверки ищет дефект только в исходных файлах (а не в заголовках).

Риск

Стандарт C11 (раздел 7.1.4) позволяет переопределить большинство макросов в качестве объектов. Чтобы получить доступ к объекту, а не к макросу в исходном файле, выполните одно из следующих действий.

  • Повторно обозначить идентификатор как внешнюю переменную или функцию.

  • Для функциональных макросов заключите имя идентификатора в скобки.

При попытке использовать эти стратегии для макросов, которые не могут быть переопределены как объекты, возникает ошибка.

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

Не используйте идентификаторы таким образом, чтобы макро-расширение было подавлено.

  • Не следует повторно объявлять идентификаторы как внешние переменные или функции.

  • Для функциональных макросов не следует заключать имя макроса в круглые скобки.

Пример - Использование assert в качестве функции
#include<assert.h>
typedef void (*err_handler_func)(int);

extern void demo_handle_err(err_handler_func, int);

void func(int err_code) {
    extern void assert(int);   
    demo_handle_err(&(assert), err_code);
}

В этом примере assert макрос переопределен как внешняя функция. При передаче в качестве аргумента demo_handle_err, идентификатор assert заключён в круглые скобки, что подавляет использование assert макро.

Коррекция - использование assert как макро

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

#include<assert.h>
void demo_handle_err(int err_code) {
    assert(err_code == 0);                   
}

void func(int err_code) {
    demo_handle_err(err_code);          
}

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

Группа: 49. Разное (MSC)
Представлен в R2019a

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

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

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