Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaration rule in struct typedef

I'm reading 'The C Programming Language' and encountered a problem about typedef of struct. The code is like this:

typedef struct tnode *Treeptr;
typedef struct tnode { /* the tree node: */
    char *word; /* points to the text */
    int count; /* number of occurrences */
    struct tnode *left; /* left child */
    struct tnode *right; /* right child */
} Treenode;

By the time we write

typedef struct tnode *Treeptr;

tnode is still not declared yet, but we don't get any compilation error, but when we change the statement above into:

typedef Treenode *Treeptr;

We get compilation error:

error: parse error before '*' token
warning: data definition has no type or storage class

What causes the difference? Isn't "struct tnode" the same as "Treenode"?

like image 792
Rain Avatar asked Nov 09 '12 06:11

Rain


People also ask

Can we typedef in declaring structure?

You can declare a typedef name for a pointer to a structure or union type before you define the structure or union type, as long as the definition has the same visibility as the declaration. Typedef names can be used to improve code readability.

What is typedef declaration?

The typedef declaration provides a way to declare an identifier as a type alias, to be used to replace a possibly complex type name.

Should you use typedef with struct?

In general, a pointer, or a struct that has elements that can reasonably be directly accessed should never be a typedef.


1 Answers

You can't use a type before it is defined.

With the typedef struct tnode { ... } Treenode; declaration, the type Treenode is not defined until the semi-colon is reached.

The situation with typedef struct tnode *Treeptr; is different. This tells the compiler 'there is a structure type called struct tnode, and the type Treeptr is an alias for a pointer to a struct tnode'. At the end of that declaration, struct tnode is an incomplete type. You can create pointers to incomplete types but you cannot create variables of the incomplete type (so you could define Treeptr ptr1; or struct tnode *ptr2; and they are the same type, but you could not define struct tnode node;).

The body of the struct tnode could be written as:

typedef struct tnode
{
    char    *word;
    int      count;
    Treeptr  left;
    Treeptr  right;
} Treenode;

because Treeptr is a known alias for the type struct tnode * before the structure is defined. You can't use Treenode *left; because Treenode is not a known alias until the final semi-colon is reached (roughly speaking).

like image 174
Jonathan Leffler Avatar answered Oct 03 '22 09:10

Jonathan Leffler