The typedef keyword in C
By Flavio Copes
Learn how the typedef keyword in C lets you create new type names from existing types, like turning int into NUMBER, and why it shines with structs and enums.
The typedef keyword in C lets you define a new name for an existing type.
Starting from the built-in C types, we can create our own type names using this syntax:
typedef existingtype NEWTYPE;
The new name is usually, by convention, uppercase. This is to distinguish it more easily, and immediately recognize it as a type.
For example we can define a new NUMBER type that is an int:
typedef int NUMBER;
and once you do so, you can define new NUMBER variables:
NUMBER one = 1;
Now you might ask: why? Why not just use the built-in type int instead?
Keep in mind typedef creates an alias, not a new type. The compiler treats NUMBER and int as the same thing, so you get no extra type checking.
The value is in readability, and in hiding details that might change. The standard library uses this a lot. size_t, time_t and the fixed-width types in stdint.h like uint8_t are all typedefs. Your code says what the value means, and the underlying type can differ between platforms.
But typedef gets really useful when paired with two things: structures and enumerated types.
How does typedef work with structs?
Without typedef, you must repeat the struct keyword every time you declare a variable:
struct person {
char name[40];
int age;
};
struct person flavio = { "Flavio", 37 };
With typedef you define the structure and the type name in one go:
typedef struct {
char name[40];
int age;
} PERSON;
PERSON flavio = { "Flavio", 37 };
Every declaration gets shorter, and the struct keyword disappears from the rest of the program.
How does typedef work with enums?
The same applies to enumerated types:
typedef enum {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday
} WEEKDAY;
WEEKDAY today = wednesday;
What happens with pointers?
You might see #define used to create type names too. Don’t do that. The two behave differently with pointers.
With typedef, the alias covers the whole type:
typedef char *STRING;
STRING first, second; //both are char *
With a macro, only the first variable gets the pointer:
#define STRING char *
STRING first, second; //first is char *, second is char
The macro is replaced textually, so the line becomes char *first, second;. The * binds to first only. Use typedef for type names, never #define.
One more thing about pointer typedefs: they hide the fact that a variable is a pointer. For example const STRING s means the pointer is const, not the characters it points to. Many codebases avoid hiding pointers behind typedefs for this reason.