Question

Est-ce "sûr"? donner des noms de macros comme arguments à d'autres macros pour simuler des fonctions d'ordre supérieur?

I.e. Où devrais-je regarder pour ne pas me tirer une balle dans le pied?

Voici quelques extraits:

#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);

Qu'en est-il de l'application partielle, puis-je le faire? :

#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);

Et puis-je définir une macro dans une macro?

#define apply_first(new_macro, macro, arg) #define new_macro(x) macro(arg,x)
Était-ce utile?

La solution

Si vous souhaitez utiliser le préprocesseur autant que possible, essayez boost.preprocessor .

Mais sachez qu'il n'est pas prudent de le faire. Les virgules, par exemple, posent un grand nombre de problèmes lors de l'utilisation de pré-processeurs. N'oubliez pas que les préprocesseurs ne comprennent pas (ou n'essayent même pas de comprendre) le code qu'ils génèrent.

Mon conseil de base est "ne le faites pas" ou "faites-le aussi prudemment que possible".

Autres conseils

J'ai mis en place un framework de tests unitaires pourris et petits totalement dans le pré-processeur c. Plusieurs dizaines de macro, beaucoup de macro est un argument pour un autre type de macro.

Ce genre de chose n'est pas "safe". dans le sens des meilleures pratiques du terme. Il existe des moyens subtils et très puissants pour se tirer une balle dans le pied. Le projet de tests unitaires est un jouet qui est devenu incontrôlable.

Je ne sais pas si vous pouvez imbriquer les définitions de macro. J'en doute, mais je vais essayer ... gcc ne l'aime pas et répond avec

  

nested_macro.cc:8: erreur: stray '#' dans le programme
  nested_macro.cc:3: erreur: constructeur attendu, destructeur ou conversion de type avant '(' jeton

  nested_macro.cc:3: erreur: déclaration attendue avant le jeton '}'

Auto-connexion : si vous êtes intéressé, vous trouverez la structure de test unitaire à https://sourceforge.net/projects/dut/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top