CERT C: Rec. PRE10-C

Перенос мультистатементных макросов в цикл do-while

Описание

Определение правила

Перенос мультистатементных макросов в цикл do-while.[1]

Реализация Polyspace

Эта проверка проверяет наличие макроса с несколькими операторами.

Примеры

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

Проблема

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

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

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

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

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