Есть ли способ написать макросы с переменным списком аргументов в Visual C++?

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

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

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

9 ответов

Решение

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

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

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

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

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

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

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

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

#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\n", "Hello World"));

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

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

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

#if defined(DETAILED_DEBUG)
#define DBGPRINT fprintf
#else
__forceinline void __DBGPRINT(...){}
#define DBGPRINT __DBGPRINT
#endif

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

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

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

#  define DBGPRINTF(fmt,...) \
    do { \
        printf(fmt, __VA_ARGS__); \
    } while(0)

Ищите "VA_ARGS" и va_list в MSDN!

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

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

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

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

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

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

Другие вопросы по тегам