exponenta event banner

Макрос завершается точкой с запятой

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

Описание

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

Риск

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

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

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

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

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

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

Примеры

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

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

Информация о результатах

Группа: Надлежащая практика
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: SEMICOLON_TERMINATED_MACRO
Воздействие: Низкий
Представлен в R2020a