2016-04-29 23 views
7

Ho la seguente paio di C macro del preprocessore che uso:Aggiunta 0 in un elenco di parametri macro incompleta

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4 
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__, 0, 0, 0, 0) 

Quando si chiama FILL_PARAMS con 1, 2 o 3 parametri, il più tardi (non specificata) sono trasformati in 0 come previsto, ma quando non si forniscono argomenti c'è un errore.

C'è un modo per aggiungere il supporto per no-parametri?

Chiarimento:
Attualmente i seguenti usi sono supportati:

FILL_PARAMS(1)   // => 1, 0, 0, 0 
FILL_PARAMS(1, 2)  // => 1, 2, 0, 0 
FILL_PARAMS(1, 2, 3) // => 1, 2, 3, 0 

E voglio aggiungere il supporto per il seguente caso limite:

FILL_PARAMS()   // => 0, 0, 0, 0 

aiuto sarà il benvenuto.

+0

Può essere fatto con qualche sforzo. Dai un'occhiata a [come è stato fatto qui] (http://stackoverflow.com/questions/34713046/what-is-the-meaning-of-this-c-macro/34713272) –

+2

Cosa c'è di sbagliato nell'uso di 'FILL_PARAMS (0) 'per il caso vuoto? – Leandros

+0

@Leandros. Ma questo può essere anche un limite .. – sjsam

risposta

2

trovato una soluzione hack-ish:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4 
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__ + 0, 0, 0, 0, 0) 

che funziona con at-almeno i seguenti test-casi.

int i = 120; 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS()); 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(i)); 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1)); 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2)); 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3)); 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3, 4)); 
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3, i)); 
0

È possibile raggiungere questo obiettivo in diversi modi, il modo più semplice è quello di utilizzare

FILL_PARAMS(0) 

a seconda del caso vuoto.

Un altro, più complesso e ingombrante da utilizzare modo è quello di avere sempre la virgola dopo l'ultimo parametro:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4 
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__ 0, 0, 0, 0) 

/* called like: */ 
FILL_PARAMS() 
FILL_PARAMS(1,) 
FILL_PARAMS(1,2,) 
FILL_PARAMS(1,2,3,) 

o per essere un po 'creativo con l'estensione GCCS virgola deglutizione:

#define TAKE4(a1, a2, a3, a4, a5, ...) a2, a3, a4, a5 
#define FILL_PARAMS(...) TAKE4(0, ##__VA_ARGS__, 0, 0, 0, 0) 
Problemi correlati