exponenta event banner

CERT C: Rec. PRE11-C

Не завершайте определения макросов точкой с запятой

Описание

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

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

Реализация Polyspace

Эта проверка проверяет макрос, завершенный точкой с запятой.

Примеры

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

Проблема

Macro terminated with a semicolon происходит, когда макрос, который вызывается по крайней мере один раз, имеет определение, заканчивающееся точкой с запятой.

Риск

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

Например, рассмотрим макрос:

#define INC_BY_ONE(x) ++x;
Если используется в выражении:
res = INC_BY_ONE(x)%2;
выражение разрешается в:
res = ++x; %2;
Значение x+1 назначается res, что, вероятно, непреднамеренно. Левый автономный оператор %2; является действительным кодом С и может быть обнаружен только путем включения строгих предупреждений компилятора.

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

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

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

Пример - Ложная точка с запятой в определении макроса
#define WHILE_LOOP(n) while(n>0);

void performAction(int timeStep);

void main() {
    int loopIter = 100;
    WHILE_LOOP(loopIter) {
        performAction(loopIter);
        loopIter--;
    }
}

В этом примере дефект возникает из-за определения макроса WHILE_LOOP(n) заканчивается точкой с запятой. В результате создания точки с запятой while цикл имеет пустое тело, и следующие операторы выполняются только один раз. Вероятно, предполагалось, что цикл должен запускаться 100 раз.

Коррекция - удалить точку с запятой из определения макроса

Удалите конечную точку с запятой из определения макроса. Пользователи макроса могут при необходимости добавить точку с запятой после макроса. В этом примере точка с запятой не требуется.

#define WHILE_LOOP(n) while(n>0)

void performAction(int timeStep);

void main() {
    int loopIter = 100;
    WHILE_LOOP(loopIter) {
        performAction(loopIter);
        loopIter--;
    }
}

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

Группа: Рек. 01. Препроцессор (PRE)
Введенный в R2020a

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

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

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