Ну что же потрачу немного времени на изыскания:
1. Обратимся к MSDN:
http://msdn.microsoft.com/en-us/library/kb57fad8.aspxtype va_arg(
va_list arg_ptr,
type
);
void va_end(
va_list arg_ptr
);
void va_start(
va_list arg_ptr
); // (UNIX version)
void va_start(
va_list arg_ptr,
prev_param
); // (ANSI version)
видим 2 va_start - Windows версия требует в качестве второго аргумента - последний аргумент переданный в функцию до ...
спрашивается: Зачем? - Обращаемся к коду va_start (который согласно стандарту C99 макрос)
#define va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
Т.е. используется первый аргумент, что бы от него отсчитать смещение и получить адрес начала списка.
тут всё понятно без первого параметра никуда не деться (если не использовать хитрости конечно)
Обращаем свой взгляд на UNIX версию
void va_start(
va_list arg_ptr
); // (UNIX version)
Смотрим man и снова две версии va_start(va_list) и va_start(va_list, paramN). Это становится интересно.
Обращаемся к стандарту C++, он нас отправляет к стандарту C99
va_start(va_list) в стандарте отсутствует (что логично, с какой стати там будет platform specific)
va_start(va_list, paramN) в стандарте присутствует, paramN - оказывается не номером параметра, а идентификатором (как мы это видели в MSDN)
Теория закончилась теперь практика в gcc и VC++.
Оба компилятора разрешаю объявлять функции вида
это радует
оба поддерживают va_start с двумя параметрами
и оба же не не поддерживают с одним параметром
И так, в принципе не что не мешает создавать функции вида void f(...), но возникают проблемы с получением доступа к параметрам
решения:
1. макрос скрывающий первый фиктивный параметр
2. если знаешь asm и как ведёт себя c++ код, то проблема решается довольно просто. в gcc можно покопать в сторону волшебной функции __builtin_va_start
В любом случае придётся решать проблему определения окончания списка параметров
Частые решения:
1. Среди параметров последним передают магическое число
2. По одному из первых параметров можно определить сколько еще параметров надо прочитать (printf, например)