Passando un’ellissi ad un’altra funzione variadica

Ho circa 30 funzioni variadiche. Ognuno accetta un percorso come argomento finale, ad esempio:

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

In ogni funzione, devo verificare che il formato espanso sia inferiore o uguale a una certa dimensione. Quindi, mi trovo a copiare / incollare lo stesso pezzo di codice per verificare quanti caratteri vsnprintf() non sono stati stampati, impostare errno conseguenza e salvare la scrittura.

Quello che vorrei fare è scrivere una funzione per farlo, che restituisca una stringa allocata staticamente (espansa) che è nota per essere una dimensione sicura o una stringa appena inizializzata in caso di errore, che potrebbe essere verificata con NULL. I controlli devono anche determinare se la stringa è un percorso assoluto o relativo, che influenza la dimensione sicura della stringa. È un sacco di codice duplicato e sta iniziando a puzzare.

C’è un modo per passare il contenuto dell’elipsis dalla voce della mia funzione a un’altra funzione? O devo prima chiamare va_start() e poi passare la va_list alla funzione helper?

Modificare:

Non sono affatto contrario a passare la va_list , volevo solo assicurarmi che nient’altro esistesse. Mi sembra che il compilatore capisca dove iniziano gli argomenti variadici, quindi ero solo curioso di sapere se li avrei passati.

Non puoi, puoi solo passare gli argomenti come una va_list . Vedi le domande frequenti su comp.lang.c.

In generale, se stai scrivendo funzioni variadiche (cioè funzioni che richiedono un numero variabile di argomenti) in C, dovresti scrivere due versioni di ciascuna funzione: una che prende un’ellissi ( ... ) e una che prende una va_list . La versione che va_start puntini di sospensione dovrebbe chiamare va_start , chiamare la versione prendendo una va_list , chiamare va_end e restituire. Non c’è bisogno di duplicare il codice tra le due versioni della funzione, dato che si chiama l’altra.

Probabilmente puoi usare macro variadic – come questo:

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

NB! I macro Variadic sono solo C99

Devi passare va_list all’helper.

Non so se questo ti sarà d’aiuto, puoi accedere alle variabili per riferimento. Questo è un po ‘un trucco subdolo, ma sfortunatamente non ti permetterà di usare i puntini di sospensione nella definizione della funzione finale.

 #include  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; } 

Sul mio pc esce

 $ ./a.out BFFEB0B0 4 BFFEB0B4 6 BFFEB0B8 7 BFFEB0BC 8 BFFEB0C0 0