Передача эллипсиса в другую вариационную функцию
У меня есть приблизительно 30 вариационных функций. Каждый принимает путь в качестве последнего аргумента, например:
bool do_foo(struct *f, int q, const char *fmt, ...)
В каждой функции я должен проверить, что расширенный формат меньше или равен определенному размеру. Итак, я обнаружил, что копирую/вставляя один и тот же фрагмент кода, чтобы проверить, сколько символов vsnprintf()
не печаталось, установите errno
соответственно и выйдите из записи.
Что бы я хотел сделать, это написать функцию для этого, которая вернет статически выделенную (расширенную) строку, которая, как известно, является безопасным размером, или новая инициализированная строка при сбое, которую можно проверить с помощью NULL. Проверки также должны определять, является ли строка абсолютным или относительным путем, что влияет на безопасный размер строки. Это много дублирующего кода, и он начинает пахнуть.
Есть ли способ передать содержимое elipsis из моей функции в другую функцию? Или мне нужно сначала вызвать va_start()
, а затем передать va_list
вспомогательной функции?
Edit:
Я вовсе не против передачи va_list
помощнику, я просто хотел убедиться, что ничего больше не существует. Мне кажется, что компилятор понимает, где начинаются переменные аргументы, поэтому мне было просто любопытно, могу ли я сказать, чтобы передать их.
Ответы
Ответ 1
Вы не можете, вы можете передавать аргументы только как va_list
. См. comp.lang.c FAQ.
В общем случае, если вы пишете вариативные функции (то есть функции, которые принимают переменное количество аргументов) в C, вы должны написать две версии каждой функции: одну, которая принимает многоточие (...
), и который принимает a va_list
. Версия с эллипсисом должна вызывать va_start
, вызывать версию с va_list
, вызывать va_end
и возвращать. Нет необходимости дублировать код между двумя версиями функции, так как один вызывает другой.
Ответ 2
Возможно, вы можете использовать переменные макросы - например:
#define FOO(...) do { do_some_checks; myfun(__VA_ARGS__); } while (0)
NB! Макросы Variadic имеют только C99
Ответ 3
Вам нужно передать va_list помощнику.
Ответ 4
Я не знаю, поможет ли это, вы можете получить доступ к переменным по ссылке. Это своего рода хитроумный трюк, но, к сожалению, он не позволит использовать эллипсис в определении окончательной функции.
#include <stdio.h>
void print_vars(int *n)
{
int i;
for(i=0;i<=*n;i++)
printf("%X %d ", (int)(n+i), *(n+i));
printf("\n");
}
void pass_vars(int n, ...)
{
print_vars(&n);
}
int main()
{
pass_vars(4, 6, 7, 8, 0);
return 0;
}
На моем компьютере он выдает
$ ./a.out
BFFEB0B0 4 BFFEB0B4 6 BFFEB0B8 7 BFFEB0BC 8 BFFEB0C0 0