it-swarm.com.ru

Передача многоточия в другую переменную функцию

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

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

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

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

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

Edit:

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

65
Tim Post

Вы не можете, вы можете передавать аргументы только как va_list. Смотрите comp.lang.c FAQ .

В общем, если вы пишете функции с переменным числом (то есть функции, которые принимают переменное число аргументов) в C, вы должны написать две версии каждой функции: одну, которая принимает многоточие (...), и одну, которая принимает va_list , Версия с Ellipsis должна вызвать va_start, вызвать версию с va_list, вызвать va_end и вернуться. Нет необходимости дублировать код между двумя версиями функции, так как одна вызывает другую.

68
Adam Rosenfield

Вероятно, вы можете использовать переменные макросы - вот так:

#define FOO(...)  do { do_some_checks; myfun(__VA_ARGS__); } while (0)

NB! Variadic макросы только для C99

10
qrdl

Я не знаю, поможет ли это, вы можете получить доступ к переменным по ссылке. Это своего рода хитрый трюк, но, к сожалению, он не позволит вам использовать Ellipsis в окончательном определении функции.

#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
1
Sepero

Вы должны передать va_list помощнику.

0
Andrew Grant