Есть ли способ написать макросы с переменным списком аргументов в Visual C ++? - PullRequest
16 голосов
/ 15 сентября 2008

Насколько я знаю, в gcc вы можете написать что-то вроде:

#define DBGPRINT(fmt...) printf(fmt);

Есть ли способ сделать это в VC ++?

Ответы [ 9 ]

24 голосов
/ 15 сентября 2008

Да, но только после VC ++ 2005. Синтаксис для вашего примера будет:

#define DBGPRINT(fmt, ...) printf(fmt, __VA_ARGS__)

Полная ссылка здесь .

4 голосов
/ 15 сентября 2008

Если вы не хотите использовать нестандартные расширения, вы должны указать дополнительные скобки:

#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\n", "Hello World"));
4 голосов
/ 15 сентября 2008

Да, вы можете сделать это в Visual Studio C ++ в версиях 2005 и выше (не уверен насчет VS 2003). Взгляните на VA_ARGS . Вы можете сделать что-то вроде этого:

#define DBGPRINTF(fmt, ...)  printf(fmt, __VA_ARGS__)

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

Может быть странное поведение с VA_ARGS и использованием макросов. Поскольку VA_ARGS является переменной, это означает, что может быть 0 аргументов. Это может оставить вас с запятыми, где вы не собирались.

1 голос
/ 03 мая 2013

Для MSVC 7.1 (.NET 2003) это работает:

#if defined(DETAILED_DEBUG)
#define DBGPRINT fprintf
#else
__forceinline void __DBGPRINT(...){}
#define DBGPRINT __DBGPRINT
#endif
1 голос
/ 16 сентября 2008

Если вам на самом деле не нужны какие-либо функции макросов (__FILE__, __LINE__, вставка токенов и т. Д.), Вы можете рассмотреть возможность написания функции с переменным числом, используя stdargs.h. Вместо вызова printf() переменная функция может вызвать vprintf() для передачи списков переменных аргументов.

1 голос
/ 15 сентября 2008

То, что вы ищете, называется [variadic macros] (http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx).

Резюме ссылки: да, с VC ++ 2005 и выше.

0 голосов
/ 15 сентября 2008

Поиск " VA_ARGS " и va_list в MSDN!

0 голосов
/ 15 сентября 2008

Следующее должно работать. (См. Ссылку на Variadic macros )

(Пример ниже показывает фиксированные и переменные аргументы.)

#  define DBGPRINTF(fmt,...) \
    do { \
        printf(fmt, __VA_ARGS__); \
    } while(0)
0 голосов
/ 15 сентября 2008

Почти. Хотя это и страшнее (и вам, вероятно, не нужна конечная точка с запятой в самом макросе:

#define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'

Чтобы использовать это:

DBGPRINT(("%s\n", "Hello World"));

(не хватало пары паренов).

Не уверен, почему во всех негативах в исходном вопросе не указана версия VC ++, а переменные макросы поддерживаются не всеми компиляторами.

...