In order to declare a struct in C, I have been using
typedef struct Foo Foo;
and then defining it at some point below.
Why do I have to specify the name of the struct (Foo
) twice?
CodePudding user response:
The format is
typedef old_type new_type
so for
typedef struct Foo Foo;
struct Foo
is the old type and Foo
is the new type, so whenever you type Foo
it is really an alias for struct Foo
.
CodePudding user response:
struct Foo
is the type that are creating a new type alias for. The last Foo
is the name of the new type. If your struct declaration is visible, then you can write the type definition and struct declaration combination like this to avoid the duplicated Foo
:
typedef struct {
...
} Foo;
CodePudding user response:
You don't have to specify two names. You can introduce an incomplete struct type just like this:
struct Foo;
that's it. Or a complete one:
struct Foo { int x; };
Neither of these declarations introduce a name into the scope; they introduce a struct tag.
If you introduce a struct tag, you must use the struct
keyword everywhere to refer to it, e.g.
struct Foo f;
void fun(struct Foo *param);
The typedef
is used in order not to have to write struct Foo
everywhere. The type name doesn't have to be the same as the tag:
typedef struct Foo_s Foo;
Foo f;
void fun(Foo *param);
The C dialect of C changes the rules; in C struct Foo
introduces Foo
into the scope as a type name, and as a tag (for C compatibility).
One reason you might see typedef struct Foo Foo
might be that the code started as C , looking like this:
struct Foo; // Originally C only header file.
void fun(Foo *param);
Then a requirement came along that C had to be supported, at least in header files. In C, the Foo
type is not declared:
typedef struct Foo Foo; // Fix for C.
#ifdef __cplusplus
#define extern_c extern "C" // C compatible linkage for fun
#endif
void fun(Foo *param);
#ifdef __cplusplus
}
#endif
Though C may seem more convenient in this regard, its object system absolutely punishes the user with repetitions of the same identifier, like you wouldn't believe.
To define a basic class skeleton with a constructor and destructor which are not inlined in the class declaration, we have to repeat the name seven times:
class foo {
public:
foo();
~foo();
};
foo::foo()
{
}
foo::~foo()
{
}
Good thing the C programmer is at least spared from having to write class foo *fooptr
everywhere, right?