Struct (C Programming Language) - Typedef

Typedef

Typedefs can be used as shortcuts, for example:

typedef struct { int account_number; char *first_name; char *last_name; float balance; } account;

Different users have differing preferences; proponents usually claim:

  • shorter to write
  • can simplify more complex type definitions

As an example, consider a type that defines a pointer to a function that accepts pointers to struct types and returns a pointer to struct:

Without typedef:

struct point { int x; int y; }; struct point *(*point_compare_t) (struct point *a, struct point *b);

With typedef:

struct point { int x; int y; }; typedef struct point point_t; typedef point_t *(*point_compare_t) (point_t *a, point_t *b);

If neither typedef were used in defining a function that takes a pointer to a type of the above function pointer, the following code would have to be used. Although valid, it becomes increasingly hard to read quickly.

/* Using the struct point type from before */ /* Define a function that returns a pointer to the biggest point, using a function to do the comparison. */ struct point * biggest_point (size_t size, struct point *points, struct point *(*point_compare) (struct point *a, struct point *b)) { int i; struct point *biggest = NULL; for (i=0; i < size; i++) { biggest = point_compare(biggest, points + i); } return biggest; }

Now with all of the typedefs being used the complexity of the function signature is drastically reduced.

/* Using the struct point type from before and all of the typedefs */ /* Define a function that returns a pointer to the biggest point, using a function to do the comparison. */ point_t * biggest_point ( size_t size, point_t * points, point_compare_t point_compare ) { int i; point_t * biggest = NULL; for (i=0; i < size; i++) { biggest = point_compare(biggest, points + i); } return biggest; }

However, there are a handful of disadvantages in using them:

  • They pollute the main namespace (see below), however this is easily overcome with prefixing a library name to the type name.
  • Harder to figure out the aliased type (having to scan/grep through code), though most IDEs provide this lookup automatically.
  • Typedefs do not really "hide" anything in a struct or union — members are still accessible (account.balance)
    (To really hide struct members, one needs to use 'incompletely-declared' structs.)
/* Example for namespace clash */ typedef struct account { float balance; } account; struct account account; /* possible */ account account; /* error */

Read more about this topic:  Struct (C Programming Language)