Как определить макрос с несколькими операторами - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь определить макрос, который имеет две строки / инструкции, это похоже на:

#define FLUSH_PRINTF(x) printf(x);fflush(stdout);

, но он не может работать из-за ограничения, с которым макросы C не могут работать с ';'.

Есть ли какой-нибудь разумный способ обойти это?

PS: Я знаю, что верхний пример странный, и я должен использовать что-то вроде нормальной функции. , но это простопростой пример, на котором я хочу задать вопрос о как определить несколько операторов Macro .

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Лучшее решение - написать функцию.Я не понимаю, зачем вам нужен макрос.

Что касается того, как сделать это с макросом, просто оберните его в {}:

#define FLUSH_PRINTF(x) { printf(x);fflush(stdout); }

Этоотлично в соответствии с C11 6.8, в результате чего получается составной оператор :

statement:
  labeled-statement
  compound-statement
  expression-statement
  selection-statement

Если вы хотите разрешить опасный стиль if без скобок (плохая идея), например:

if(x)
  FLUSH_PRINTF(x);
else
  FLUSH_PRINTF(y);

, тогда вы должны использовать трюк do while(0), чтобы обернуть макрос:

#define FLUSH_PRINTF(x) do { printf(x);fflush(stdout); } while(0)
0 голосов
/ 17 мая 2018

Это подходящее время для использования идиомы do { ... } while (0).Это также подходящее время для использования переменных макропараметрических аргументов .

#define FLUSH_PRINTF(...) \
    do { \
        printf(__VA_ARGS__); \
        fflush(stdout); \
    } while (0)

Вы также можете сделать это с помощью функции-обертки, но это будет более типично из-за использования дополнительных шаблонов.с использованием vprintf.

 #include <stdarg.h>
 #include <stdio.h>

 /* optional: */ static inline 
 void
 flush_printf(const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
     vprintf(fmt, ap);
     va_end(ap);
     fflush(stdout);
 }
...