Возможно ли иметь в C вариадную функцию без невариатического параметра? - PullRequest
16 голосов
/ 12 апреля 2010

У меня есть следующая функция:

void doStuff(int unusedParameter, ...)
{
    va_list params;
    va_start(params, unusedParameter);
    /* ... */
    va_end(params);
}

Как часть рефакторинга, я хотел бы удалить неиспользуемый параметр, не изменяя реализацию функции. Насколько я могу судить, невозможно использовать va_start, когда у вас нет последнего невариантного параметра для ссылки. Есть ли способ обойти это?

Справочная информация: На самом деле это программа на C ++, поэтому я мог бы использовать магию перегрузки операторов, как предлагалось здесь , но я надеялся, что на этом этапе не нужно менять интерфейс.

Существующая функция выполняет свою работу, требуя, чтобы список переменных-переменных заканчивался нулем, и сканировала на NULL, поэтому ей не нужен ведущий аргумент, чтобы сказать, сколько у нее аргументов.

В ответ на комментарии: у меня нет для удаления неиспользуемого параметра, но я бы сделал это, если бы был чистый способ сделать это. Я надеялся, что будет что-то простое, что я пропустил.

Ответы [ 2 ]

13 голосов
/ 12 апреля 2010

В GCC у вас есть обходной путь: вы можете определить макрос с переменным числом аргументов, а затем добавить фиктивный параметр в расширение:

#define doStuff(...) realDoStuff(0, __VA_ARGS__)
3 голосов
/ 12 апреля 2010

Вы можете либо оставить все как есть, либо использовать va_list, присвоить ему псевдоним (если это GCC), как указали другие, либо сделать что-то в соответствии с интерфейсом exec(2) - передав массив указателей, требующих NULL терминатор:

/* \param args  NULL-terminated array of
 *              pointers to arguments.
 */
void doStuff( void* args[] );

В любом случае было бы намного лучше реорганизовать интерфейс, чтобы каким-либо образом воспользоваться преимуществами системы типов - возможно, перегрузить используемые типы аргументов:

void doStuff( int );
void doStuff( const std::string& );
void doStuff( const MyFancyAppClass& );

Надеюсь, это поможет.

...