Есть ли способ написать макросы с переменным списком аргументов в 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)
Почти. Хотя это и страшнее (и, возможно, вам не нужна конечная точка с запятой в самом макросе:
#define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'
Чтобы использовать это:
DBGPRINT(("%s\n", "Hello World"));
(не хватало пары паренов).
Не уверен, почему во всех минусах в исходном вопросе не указана версия VC++, а переменные макросы поддерживаются не всеми компиляторами.