Domanda

È " sicuro " dare nomi di macro come argomenti ad altre macro per simulare funzioni di ordine superiore?

vale a dire. dove dovrei cercare di non spararmi al piede?

Ecco alcuni frammenti:

#define foreach_even(ii, instr) for(int ii = 0; ii < 100; ii += 2) { instr; }
#define foreach_odd(ii, instr)  for(int ii = 1; ii < 100; ii += 2) { instr; }

#define sum(foreach_loop, accu) \
  foreach_loop(ii, {accu += ii});

int acc = 0;
sum(foreach_even, acc);
sum(foreach_odd, acc);

Che dire dell'applicazione parziale, posso farlo? :

#define foreach(ii, start, end, step, instr) \
  for(int ii = start; ii < end; ii += step) { instr; }

#define foreach_even(ii, instr) foreach(ii, 0, 100, instr)
#define foreach_odd(ii, instr)  foreach(ii, 1, 100, instr)

#define sum(foreach_loop, accu) \
  foreach_loop(ii, {accu += ii});

int acc = 0;
sum(foreach_even, acc);
sum(foreach_odd, acc);

E posso definire una macro all'interno di una macro?

#define apply_first(new_macro, macro, arg) #define new_macro(x) macro(arg,x)
È stato utile?

Soluzione

Se stai utilizzando il preprocessore il più possibile, potresti provare boost.preprocessor .

Ma tieni presente che non è non sicuro farlo. Le virgole, ad esempio, causano un gran numero di problemi quando si usano i preprocessori. Non dimenticare che i preprocessori non comprendono (o provano nemmeno a capire) il codice che stanno generando.

Il mio consiglio di base è "non farlo" o "farlo nel modo più prudente possibile".

Altri suggerimenti

Ho implementato un framework per test di unità poco marcio interamente in preprocessore c. Diverse dozzine di macro, molte macro sono un argomento per un'altra roba di tipo macro.

Questo genere di cose non è non " sicuro " nel senso delle migliori pratiche della parola. Ci sono modi sottili e molto potenti per spararti al piede. Il progetto di unit testing è un giocattolo sfuggito di mano.

Non so se è possibile nidificare definizioni di macro. Ne dubito, ma vado a provare ... gcc non piace e risponde con

  

nested_macro.cc:8: errore: "#" smarrito nel programma
  nested_macro.cc:3: errore: conversione prevista del costruttore, del distruttore o del tipo prima del '(' token
  nested_macro.cc:3: errore: dichiarazione prevista prima del token "}"

Self plug : se sei interessato, il framework di unit testing può essere trovato su https://sourceforge.net/projects/dut/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top