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);          
}

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

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

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

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