tags:

views:

59

answers:

1

I've defined 2 macros:

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

The purpose of these macros is to create a C struct with some predefined members (retain count and deallocator) function and automatically create an allocator function.

Now, when I use these macros as this:

HCL_CLASS(Dummy)
int whatever;
HCL_CLASS_END(Dummy)

they get expanded into this (taken directly from 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; }

And when I try to compile this, I get two errors:

  • "Expected ')' before '*' token" on line which calls HCL_CLASS
  • "Expected ';' before 'int'" on line which declares the int struct member

I cannot see a reason for these errors. I'd be grateful if you'd help me find it. Thanks.

+5  A: 

You need to use the struct as the parameter to dealloc, not the 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; }

This is because the typedef isn't complete where you declare dealloc.

Also, in C++ your struct name and typedef must not collide. So I added an underscore to the struct name via _##TYPE.

Heath Hunnicutt
Thanks, that helped. I'll accept this answer as correct as soon as stackoverflow lets me do so :)
Jakub Lédl
Yay glad to hear it. If you are using a very strict compiler in C mode you will have to distinguish the struct name from the typedef name, also.
Heath Hunnicutt
Actually, the struct and typedef names *can* 'collide' in C, though i'm fairly sure *C++* requires them to be distinct.
David X
@David X You are correct, I had the reversed. Editted for posterity.
Heath Hunnicutt