tags:

views:

41

answers:

1

I'm trying to forward declare a class with the _may_alias attribute, but GCC gives an error when I attempt to do so:

struct __attribute__((__may_alias__)) MyType;
MyType* foo();

typedef struct  __attribute__((__may_alias__)) MyType { ... } MyType;
MyType* foo() {}

Gives the error: testc.c:4: error: redefinition of typedef ‘A’
testc.c:1: note: previous declaration of ‘A’ was here
testc.c:5: error: conflicting types for ‘foo’
testc.c:2: note: previous declaration of ‘foo’ was here

Is there a way to do this?

+3  A: 

C doesn't allow to do a typedef twice. In addition you have to distinguish between the forward declaration of a struct and of a typedef. The easiest way to have that is to use the same token as struct tag and as a typedef identifier. Without the attribute stuff, in standard C this would look like:

/* this is a forward declaration of struct and typedef */
typedef struct MyType MyType;
MyType* foo(void);

/* declare the struct as a struct */
struct MyType { };
MyType* foo(void) { return NULL; }

Now comes the play with the attributes. You'd have to find out to which it applies to the struct declaration or the typedef. My guess is for the struct, but a quick look in to the gcc info should show you that.

/* this is a forward declaration of struct and typedef */
typedef __attribute__((__may_alias__)) struct MyType MyType;

/* declare the struct as a struct */
__attribute__((__may_alias__)) struct MyType { };
Jens Gustedt
sorry, I fixed my code to have the proper attribute instead of a macro used to generate it. This might have confused you.
Nathaniel Flath
@Nathaniel: ok, clearer, edited my reply accordingly
Jens Gustedt