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)
Этот макрос является соответствующим, чтобы расшириться во всех контекстах. 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