CERT C: Rec. PRE11-C

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

Описание

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

Не завершайте макроопределения с semicolon.[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--;
    }
}

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

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

[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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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