Passando uma elipse para outra função variádica [duplicado]
-
22-08-2019 - |
Pergunta
Esta questão já tem uma resposta aqui:
- encaminhar uma chamada de uma função em C variádica 10 respostas
Eu tenho cerca de 30 funções variádicos. Cada um aceita um caminho como argumento final, por exemplo:.
bool do_foo(struct *f, int q, const char *fmt, ...)
Em cada função, eu tenho que verificar que o formato expandido é menor ou igual a um determinado tamanho. Então, eu encontro-me copiar / colar o mesmo pedaço de código para verificar quantos caracteres vsnprintf()
não imprimir, conjunto errno
em conformidade e socorrer da escrita.
O que eu gostaria de fazer é escrever uma função para fazer isso, o que retornar uma string alocada estaticamente (expandido) que é conhecido por ser um tamanho seguro, ou string recém-inicializado em caso de falha, o que pode ser verificado contra NULL. As verificações também tem que determinar se a cadeia é um caminho absoluto ou relativo, o que influencia o tamanho seguro do string. É um monte de código duplicado e está começando a cheiro.
Existe uma maneira que eu posso passar o conteúdo do elipsis da entrada da minha função para outra função? Ou eu tenho que chamar va_start()
primeiro, e depois passar o va_list
para a função de ajudante?
Editar:
Eu não estou nada contrário de passar a va_list
ao ajudante, eu só queria ter certeza de que nada mais existia. Parece-me que o compilador entende que os argumentos variádicos começar, então eu estava apenas curioso se eu pudesse dizer-lhe para passá-los.
Solução
Você não pode, você só pode passar os argumentos como um va_list
. Veja a comp.lang.c FAQ .
Em geral, se você estiver escrevendo funções variádicos (isto é, funções que levam um número variável de argumentos) em C, você deve escrever duas versões de cada função: um que leva uma elipse (...
), e que leva um va_list
. A versão tomar uma elipse deve chamar va_start
, chamar a versão tomar um va_list
, va_end
chamada e retorno. Não há necessidade de duplicação de código entre as duas versões da função, uma vez que um chama o outro.
Outras dicas
Provavelmente você pode usar macros variádicos - como este:
#define FOO(...) do { do_some_checks; myfun(__VA_ARGS__); } while (0)
Nota! macros variádicos são C99-only
Eu não sei se isso vai ajudar, você pode acessar as variáveis ??por referência. Este é tipo de um truque sorrateira, mas, infelizmente, não vai permitir que você use reticências na definição da função final.
#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;
}
No meu pc ele gera
$ ./a.out
BFFEB0B0 4 BFFEB0B4 6 BFFEB0B8 7 BFFEB0BC 8 BFFEB0C0 0
Você tem que passar va_list ao ajudante.