Macro with multiple statements

Макрос состоит из нескольких операторов с запятой, заключенных в скобки или нет

Описание

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

Риск

Расширение макроса в определенных контекстах, таких как if условие или цикл, может привести к непреднамеренной логике программы.

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

#define RESET(x,y) \
   x=0; \
   y=0;
В if оператор, такой как:
if(checkSomeCondition)
   RESET(x,y);
макрос расширяется до:
if(checkSomething)
   x=0;
y=0;
что может оказаться неожиданным, если необходимо, чтобы оба операторов выполнялись в if блок.

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

В определении макроса переносите несколько операторов в do...while(0) цикл.

Для образца в предыдущем примере используйте определение:

#define RESET(x,y) \
   do { \
     x=0; \
     y=0; \
   } while(0)
Этот макрос подходит для развертывания во всех контекстах. The while(0) гарантирует, что операторы выполняются только один раз.

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

Обратите внимание, что цикл необходим для правильного решения, и только упаковка операторов в скобки не устраняет проблему. Расширение макроса все еще может привести к непреднамеренному коду.

Примеры

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

#define RESET(x,y) \
   x=0; \
   y=0;

void func(int *x, int *y, int resetFlag){
    if(resetFlag)
        RESET(x,y);    
}

В этом примере дефект возникает из-за RESET макроса состоит из нескольких операторов.

Коррекция - перенос нескольких операторов макроса в do-while Цикл

Перенос операторов макроса в do..while(0) цикл в определении макроса.

#define RESET(x,y) \
   do { \
     x=0; \
     y=0; \
   } while(0)

void func(int *x, int *y, int resetFlag){
    if(resetFlag)
        RESET(x,y);    
}

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

Группа: Хорошая практика
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки : MULTI_STMT_MACRO
Влияние: Низкое
Введенный в R2020a