Home > Back-end >  Declaring a Struct in C: Why do I have to Specify the Name Twice?
Declaring a Struct in C: Why do I have to Specify the Name Twice?

Time:09-28

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?

  • Related