Подтвердить что ты не робот

Передача эллипсиса в другую вариационную функцию

У меня есть приблизительно 30 вариационных функций. Каждый принимает путь в качестве последнего аргумента, например:

bool do_foo(struct *f, int q, const char *fmt, ...)

В каждой функции я должен проверить, что расширенный формат меньше или равен определенному размеру. Итак, я обнаружил, что копирую/вставляя один и тот же фрагмент кода, чтобы проверить, сколько символов vsnprintf() не печаталось, установите errno соответственно и выйдите из записи.

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

Есть ли способ передать содержимое elipsis из моей функции в другую функцию? Или мне нужно сначала вызвать va_start(), а затем передать va_list вспомогательной функции?

Edit:

Я вовсе не против передачи va_list помощнику, я просто хотел убедиться, что ничего больше не существует. Мне кажется, что компилятор понимает, где начинаются переменные аргументы, поэтому мне было просто любопытно, могу ли я сказать, чтобы передать их.

4b9b3361

Ответ 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