tags:

views:

399

answers:

3

Going by gcc version 4.4.2, it appears that saying

typedef struct foo foo;
// more code here - like function declarations taking/returning foo*
// then, in its own source file:
typedef struct foo
{
    int bar;
} foo;

is legal in C++ but not in C.

Of course I have a body of code that compiles fine in C++ by using the foo type but it appears I must make it use struct foo (in the header file) to get it to work with some C code another developer wrote.

Is there a way to predeclare a struct typedef foo foo in gcc C without getting a "redefinition of typedef 'foo'" error when compiling for C? (I don't want the marginally illegal and less clean underscore solution of *struct typedef _foo foo*)

+7  A: 

Is this what you need?

// header (.h)
struct foo;
typedef struct foo foo;

foo *foo_create();
// etc.

// source (.c)
struct foo {
    // ...
}

I also tend to prefix my struct name with an underscore when typdefing to make its privateness clear and prevent possible name clashes.

Mike Weller
beware reserved names when using underscores, see http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier
Gregory Pakosz
Good link. I guess I'll use post-fix underscores then...
Mike Weller
A: 

I'm not sure why GCC rejects this code, but it appears it only objects because you're defining the same typedef twice.

This works:

typedef struct foo foo;

struct foo {
    int bar;
};

And this works too, with the same effect:

typedef struct foo {
    int bar;
} foo;
Jason Orendorff
+1  A: 

One of the differences between C++ and C is that in C++ it is legal to make a repetitive typedef in the same scope as long as all these typedef are equivalent. In C repetitive typedef is illegal.

typedef int TInt;
typedef int TInt; /* OK in C++. Error in C */

This is what you have in your above code. If you are trying to write a code that can be compiled as both C and C++, get rid of the superfluous second typedef and just do

typedef struct foo foo;  
...
struct foo  
{  
    int bar;  
};

(although in C++ the first typedef is superfluous as well).

AndreyT