tags:

views:

123

answers:

3
+3  Q: 

struct and typedef

Are the following equivalent in C?

// #1
struct myStruct {
    int id;
    char value;
};

typedef struct myStruct Foo;

// #2
typedef struct {
    int id;
    char value;
} Foo;

If not, which one should I use and when?

(Yes, I have seen this and this.)

+5  A: 

The second option cannot reference itself. For example:

// Works:
struct LinkedListNode_ {
    void *value;
    struct LinkedListNode_ *next;
};

// Does not work:
typedef struct {
    void *value;
    LinkedListNode *next;
} LinkedListNode;

// Also Works:
typedef struct LinkedListNode_ {
    void *value;
    struct LinkedListNode_ *next;
} LinkedListNode;
Emil H
+2  A: 

No, they're not exactly equivalent.

In the first version Foo is a typedef for the named struct myStruct.

In the second version, Foo is a typedef for an unnamed struct.

Although both Foo can be used in the same way in many instances there are important differences. In particular, the second version doesn't allow the use of a forward declaration to declare Foo and the struct it is a typedef for whereas the first would.

Charles Bailey
Sorry, that was a typo. I meant to say `typedef struct myStruct Foo`
pessimopoppotamus
@pessimopoppotamus: Fixed
Charles Bailey
@Charles Thanks, can you show an example where the difference between them is apparent?
pessimopoppotamus
@pessimopoppotamus: Well like I said, the most obvious way is that in the first case you can use `typedef struct myStruct Foo;` to forward declare the `struct` and `Foo` and use it as an incomplete type (where appropriate) whereas this is just not possible with the unnamed `struct` version. You can also (of course) use `struct myStruct` as a name for the type in the first instance; there is no "full" version of the type in the second.
Charles Bailey
+2  A: 

The first form allows you to refer to the struct before the type definition is complete, so you can refer to the struct within itself or have mutually dependent types:

struct node {
  int value;  
  struct node *left;
  struct node *right;
};

typedef struct node Tree;

or

struct A;
struct B;

struct A {
  struct B *b;
};

struct B {
  struct A *a;
};

typedef struct A AType;
typedef struct B Btype;

You can combine the two like so:

typedef struct node {
  int value;
  struct node *left;
  struct node *right;
} Tree;

typedef struct A AType;  // You can create a typedef 
typedef struct B BType;  // for an incomplete type

struct A {
  BType *b;
};

struct B {
  AType *a;
};
John Bode