2009-12-04 6 views
1

que je cherchais macro qui peut développer comme ce qui suit:En ce qui concerne les macros

FILL_BUFF (4) devrait être élargie comme (0xFF, 0xFF, 0xFF, 0xFF) ... ce qui peut être la macro écrite pour ce qui précède expansion ..

+0

Je ne suis pas sûr qu'il est possible de faire exactement ce que vous voulez. – StrixVaria

+3

Qu'allez-vous faire avec cette liste entre parenthèses? En tant que valeur, cela équivaut à écrire (0xFF); comme une liste d'arguments ... qu'est-ce que tu fais avec, exactement? –

+0

@Jonathan: vraisemblablement @invisible signifie '{0xFF, 0xFF, 0xFF, 0xFF}' – DrAl

Répondre

2

PP got it - presque. Abus du préprocesseur C à nouveau. D'un autre côté, cela ne mérite rien de mieux.

#define FILL_BUFF(N) FILL_BUFF_ ## N 

#define FILL_BUFF_1 (0xFF) 
#define FILL_BUFF_2 (0xFF,0xFF) 
#define FILL_BUFF_3 (0xFF,0xFF,0xFF) 
#define FILL_BUFF_4 (0xFF,0xFF,0xFF,0xFF) 
+0

@drhirsch: même dans la même pensée. mais je ne peux pas continuer à avoir beaucoup d'expansions (il faudra peut-être jusqu'à 0 à 63)! – inquisitive

+0

0..63 n'est pas un grand ensemble pour un fichier d'en-tête. Je ne m'inquiéterais que si la liste dépassait 1 000 ou 10 000 lignes. –

2

Les macros n'ont pas de contrôles conditionnels tels que les boucles - elles sont très simples.

Il est courant de voir un groupe de macros dans un en-tête couvrant toutes les expansions communes, par ex.


#define FILL_BUFF_1 (0xFF) 
#define FILL_BUFF_2 (0xFF,0xFF) 
#define FILL_BUFF_3 (0xFF,0xFF,0xFF) 
#define FILL_BUFF_4 (0xFF,0xFF,0xFF,0xFF) 
+1

Si vous VOULEZ vraiment utiliser le FILL_BUFF (4), vous pouvez toujours avoir '#define FILL_BUFF (n) FILL_BUFF _ ## n' pour revenir à ceux définis ici. Je dois souligner que je ne le recommande pas (à part toute autre chose, il enfreint la règle MISRA 19.13 et enfreindre les règles MISRA est presque toujours une mauvaise chose à mon avis). – DrAl

+0

Mais je veux avoir la situation ci-dessus, mais en utilisant des macros – inquisitive

+4

@inquisitive: Vous ne pouvez pas toujours obtenir ce que vous voulez. –

1

Hmm, peut-être via memset:

#define FILL_BUFF(buf, n) memset(buff, 0xff, n) 

Mais je ne suis pas sûr que ce soit une bonne idée

+0

@laura: Je pense que cela devrait être memset (buf, 0xff, n); vous avez ajouté un f supplémentaire dans le mot dans la macro! :) – t0mm13b

2

Vous pouvez regarder le boost preprocessor library. En particulier, les macros BOOST_PP_REPEAT_z:

#define DECL(z, n, text) text ## n = n; 

BOOST_PP_REPEAT(5, DECL, int x) 

résultats dans:

int x0 = 0; int x1 = 1; int x2 = 2; int x3 = 3; int x4 = 4; 

Dans votre cas, vous pouvez faire:

#define FILL_BUFF_VALUE(z, n, text) text, 
#define FILL_BUFF(NPLUSONE, VALUE) { BOOST_PP_REPEAT(NPLUSONE, FILL_BUFF_VALUE, VALUE } VALUE) 

int anbuffer[] = FILL_BUFF(4 /* +1 */,0xff); // anbuffer will have length 5 afterwards 

qui élargirait à

int anbuffer[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 
+0

Est-ce que cela fonctionne avec C? –

+0

Ceci est buggé. Actuellement, il se développe à "(BOOST_PP_REPEAT_1_4-1 (FILL_BUFF_VALUE, 0xff) 0xff)" – hirschhornsalz

+0

Merci pour les commentaires. Cela fonctionne maintenant mais est un peu moche à moins qu'il y ait un moyen d'avoir "N-1" d'abord évaluer à l'intérieur des macros. – Sebastian