exponenta event banner

Макрос с несколькими операторами

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

Описание

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

Риск

Расширение макроса в определенных контекстах, таких как 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++
По умолчанию: Откл.
Синтаксис командной строки: MULTI_STMT_MACRO
Воздействие: Низкий
Представлен в R2020a