Есть ли способ написать макросы со списком переменных аргументов в Visual C++?
-
09-06-2019 - |
Вопрос
Насколько я знаю, в gcc можно написать что-то вроде:
#define DBGPRINT(fmt...) printf(fmt);
Есть ли способ сделать это в VС++?
Решение
Да, но только с VC++ 2005.Синтаксис вашего примера будет таким:
#define DBGPRINT(fmt, ...) printf(fmt, __VA_ARGS__)
Полная ссылка есть здесь.
Другие советы
Да, вы можете сделать это в Visual Studio C++ версий 2005 и более поздних (насчет VS 2003 не уверен).Взгляни на ВА_ARGS.В принципе вы можете сделать что-то вроде этого:
#define DBGPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
и переменные аргументы макроса будут переданы функции, представленной как '...' args, где вы затем сможете использовать va_args для их анализа.
Может быть странное поведение с ВА_ARGS и использование макросов.Потому что ВА_ARGS является переменной, это означает, что аргументов может быть 0.Это может привести к тому, что у вас останутся запятые там, где вы не собирались.
Если вы не хотите использовать нестандартные расширения, вам необходимо указать дополнительные скобки:
#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\n", "Hello World"));
То, что вы ищете, называется [вариативными макросами](http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx).
Краткое содержание ссылки:да, начиная с VС++ 2005.
Если вам на самом деле не нужны какие-либо функции макросов (__FILE__
, __LINE__
, вставка токенов и т. д.), возможно, вы захотите написать вариативную функцию, используя stdargs.h
.Вместо того, чтобы звонить printf()
, вариатическая функция может вызывать vprintf()
для передачи списков переменных аргументов.
Для MSVC 7.1 (.NET 2003) это работает:
#if defined(DETAILED_DEBUG)
#define DBGPRINT fprintf
#else
__forceinline void __DBGPRINT(...){}
#define DBGPRINT __DBGPRINT
#endif
Следующее должно работать.(см. ссылку на Вариативные макросы)
(Пример ниже показывает фиксированные и переменные аргументы.)
# define DBGPRINTF(fmt,...) \
do { \
printf(fmt, __VA_ARGS__); \
} while(0)
Искать "ВА_ARGS" и va_list в MSDN!
Почти.Однако это уродливее (и вам, вероятно, не нужна завершающая точка с запятой в самом макросе:
#define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'
Чтобы использовать его:
DBGPRINT(("%s\n", "Hello World"));
(не хватало пары скобок).
Не знаю, почему все негативы, в исходном вопросе не указана версия VC++, а макросы с переменным числом вариантов поддерживаются не всеми компиляторами.