I have seen many programs consisting of structures like the one below
typedef struct
{
int i;
char k;
} elem;
elem user;
Why is i
From an old article by Dan Saks (http://www.ddj.com/cpp/184403396?pgno=3):
The C language rules for naming structs are a little eccentric, but they're pretty harmless. However, when extended to classes in C++, those same rules open little cracks for bugs to crawl through.
In C, the name s appearing in
struct s { ... };
is a tag. A tag name is not a type name. Given the definition above, declarations such as
s x; /* error in C */ s *p; /* error in C */
are errors in C. You must write them as
struct s x; /* OK */ struct s *p; /* OK */
The names of unions and enumerations are also tags rather than types.
In C, tags are distinct from all other names (for functions, types, variables, and enumeration constants). C compilers maintain tags in a symbol table that's conceptually if not physically separate from the table that holds all other names. Thus, it is possible for a C program to have both a tag and an another name with the same spelling in the same scope. For example,
struct s s;
is a valid declaration which declares variable s of type struct s. It may not be good practice, but C compilers must accept it. I have never seen a rationale for why C was designed this way. I have always thought it was a mistake, but there it is.
Many programmers (including yours truly) prefer to think of struct names as type names, so they define an alias for the tag using a typedef. For example, defining
struct s { ... }; typedef struct s S;
lets you use S in place of struct s, as in
S x; S *p;
A program cannot use S as the name of both a type and a variable (or function or enumeration constant):
S S; // error
This is good.
The tag name in a struct, union, or enum definition is optional. Many programmers fold the struct definition into the typedef and dispense with the tag altogether, as in:
typedef struct { ... } S;
The linked article also has a discussion about how the C++ behavior of not requireing a typedef
can cause subtle name hiding problems. To prevent these problems, it's a good idea to typedef
your classes and structs in C++, too, even though at first glance it appears to be unnecessary. In C++, with the typedef
the name hiding become an error that the compiler tells you about rather than a hidden source of potential problems.