2010-07-11 3 views
0

J'ai défini 2 macros:Aide avec 2 macros C

#define HCL_CLASS(TYPE) typedef struct TYPE { \ 
          HCLUInt rc; \ 
          void (*dealloc)(TYPE*); 

#define HCL_CLASS_END(TYPE) } TYPE; \ 
TYPE * TYPE##Alloc() { TYPE *ptr = (TYPE *)malloc(sizeof(TYPE)); if (ptr != NULL) ptr->rc = 1; return ptr; } 

Le but de ces macros est de créer une struct C avec une fonction membres prédéfinis (conserver le nombre et deallocator) et créer automatiquement une fonction allocateur .

Maintenant, quand j'utilise ces macros comme ceci:

HCL_CLASS(Dummy) 
int whatever; 
HCL_CLASS_END(Dummy) 

ils s'étendus dans ce (pris directement à partir XCode):

typedef struct Dummy { HCLUInt rc; void (*dealloc)(Dummy*); 

int whatever; 

} Dummy; Dummy * DummyAlloc() { Dummy *ptr = (Dummy *)malloc(sizeof(Dummy)); if (ptr != ((void *)0)) ptr->rc = 1; return ptr; } 

Et quand je tente de compiler, je reçois deux erreurs:

  • "Expected ')' avant '*' jeton" en ligne qui appelle HCL_CLASS
  • "Expected"; ' avant 'int' "on line qui déclare le membre int struct

Je ne vois pas de raison pour ces erreurs. Je serais reconnaissant si vous m'aidiez à le trouver. Merci.

+1

Juste un type de style général, ne pas lancer malloc(). Cela peut cacher des problèmes potentiels en le faisant. Par exemple, supposons que vous oubliez d'inclure stdlib.h, donc malloc() est supposé renvoyer int. Si sizeof (int) et sizeof (Dummy) n'ont pas la même taille, vous pouvez imaginer la casse qui s'ensuivra. Le seul moment que vous auriez à lancer est si vous mélangez avec C++ où ne pas le faire se traduira par une erreur. C est parfaitement heureux sans la distribution, puisque malloc renvoie un pointeur vers quelque chose, pas n'importe quoi en particulier. – jer

+0

vous voulez dire sizeof (Dummy *) mais je vous +1 pour être correct en général. –

+0

Oui je le fais, la touche n'a pas enfoncé, mon erreur :) – jer

Répondre

5

Vous devez utiliser le struct comme paramètre à dealloc, pas le typedef:

#define HCL_CLASS(TYPE) typedef struct _##TYPE { \ 
          HCLUInt rc; \ 
          void (*dealloc)(struct _##TYPE*); 
         /* use struct here ^^^^^^, not the typedef */ 

#define HCL_CLASS_END(TYPE) } TYPE; \ 
TYPE * TYPE##Alloc() { TYPE *ptr = (TYPE *)malloc(sizeof(TYPE));\ 
         if (ptr != NULL) ptr->rc = 1; return ptr; } 

En effet, le typedef est pas complète où vous déclarez dealloc. En outre, en C++, votre nom de structure et typedef ne doivent pas entrer en conflit. J'ai donc ajouté un trait de soulignement au nom de la structure via _##TYPE.

+0

Merci, cela m'a aidé. Je vais accepter cette réponse comme correcte dès que stackoverflow me le permet :) –

+0

Yay heureux de l'entendre. Si vous utilisez un compilateur très strict en mode C, vous devrez également distinguer le nom de la structure du nom du typedef. –

+0

En fait, les noms struct et typedef * peuvent * 'entrer en collision' en C, bien que je sois à peu près sûr que * C++ * les oblige à être distincts. –