Types can sometimes be either complex or non-descriptive. For example, the size of a data structure may return an unsigned int on one system, while on another it return an unsigned long. It would be much more helpful to a programmer to have a standard name for the type returned by an operator such as sizeof or a function that performs a similar task. Thus, the following alias for the type returned by functions and operators related to memory used is
typedef unsigned int size_t;
Thus, any time a variable is declared to be size_t, it is actually declared to be unsigned int and it will behave as an unsigned int.
One issue in C and C++ is that there is no default size of int or long. Consequently, many libraries designed for a specific system will redefine types to indicate their size:
typedef signed char S8; typedef char U8; typedef short S16; typedef unsigned short U16; typedef int S32; typedef unsigned int U32; typedef long long S64; typedef unsigned long long U64;
By default, char is unsigned while short, int, and long are signed. Now if a variable is declared to be of type U32, the programmer knows it is a 32-bit unsigned integer.
You can also define a type to be an array of a given type, such as
typedef U32 OS_SEM[2]; typedef U32 OS_MUT[3]; typedef U32 *OS_ID;
In this case, variables, arguments, and return types declared to be OS_SEM, OS_MUT, and OS_ID will be, respectively, an array of two 32-bit unsigned integers, an array of three 32-bit unsigned integers, and a pointer to a 32-bit unsigned integer.
Whenever you see a variable, argument, or return value declared to be a type that has been defined through typedef, you need only substitute the variable for the typedef symbol in the typedef definition. For example, if
typedef struct { S8 name[256]; U32 size; U16 fileID; U8 attrib; RL_TIME time; } FINFO;
and a variable is defined as an array of three instances of this type:
FINFO array[3];
this would be equivalent to
struct { S8 name[256]; U32 size; U16 fileID; U8 attrib; RL_TIME time; } array[3];
A struct may be given a name in two ways:
struct struct_name { /* fields */ }; typedef struct { /* fields */ } Struct_name;
These two can be combined:
struct struct_name { /* fields */ } Struct_name;
In the first case, you must always use the keyword struct, but in this case, the symbol struct_name can continue to be used as either a variable or a function name: prefixed by struct it means the structure, and without the prefix it refers to the function or variable. With the typedef, the defined alias is now global.
Note that the alias is defined at the end of the statement: consequently, using typedef, one cannot define a pointer to the structure within the structure. If you wanted to define a node within a linked list, and you wanted a typedef, you would have to try something like:
typedef struct struct_name { int value; struct struct_name *next; /* a pointer to this structure */ } Struct_name;