Preprocessor directive in macro argument

Вы используете директиву препроцессора в аргументе к функциональному макросу

Описание

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

Для образца, a #ifdef оператор возникает в аргументе к memcpy функция. The memcpy функция может быть реализована как макрос.

memcpy(dest, src,
    #ifdef PLATFORM1
      12
    #else
      24
    #endif
  );
Шашечные флаги аналогичного использования в printf и assert, который также может быть реализован как макросы.

Риск

Во время предварительной обработки функциональный вызов макроса заменяется телом макроса, а параметры заменяются аргументами к вызову макроса (подстановка аргумента). Предположим, макрос min() определяется следующим образом.

#define min(X, Y)  ((X) < (Y) ? (X) : (Y))
Когда вы звоните min(1,2), он заменяется телом ((X) < (Y) ? (X) : (Y)). X и Y заменяются на 1 и 2.

Согласно Стандарту C11 (раздел 6.10.3), если список аргументов в сам функциональный макрос имеет директивы предварительной обработки, подстановка аргумента во время предварительной обработки не определена.

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

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

Например, чтобы выполнить memcpy с различными аргументами, основанными на #ifdef директива, вызов memcpy несколько раз в #ifdef директивные ветви.

#ifdef PLATFORM1
    memcpy(dest, src, 12);
#else
    memcpy(dest, src, 24);
#endif

Примеры

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

#include <stdio.h>

#define print(A) printf(#A)

void func(void) {
    print(
#ifdef SW
          "Message 1"
#else
          "Message 2"
#endif
         );
}

В этом примере директивы препроцессора #ifdef и #endif происходит в аргументе функционального макроса print().

Коррекция - Используйте директивы вне макроса

Одной из возможных коррекций является использование функционального макроса несколько раз в ветвях #ifdef директива.

#include <stdio.h>

#define print(A) printf(#A)

void func(void) {
#ifdef SW
        print("Message 1");
#else  
        print("Message 2");
#endif 
}

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

Группа: Программирование
Язык: C | C++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : PRE_DIRECTIVE_MACRO_ARG
Влияние: Низкое
Введенный в R2018a