Skip to content

Instantly share code, notes, and snippets.

@theffc
Created November 26, 2015 00:04
Show Gist options
  • Save theffc/fafff463bc7ad5de2c1b to your computer and use it in GitHub Desktop.
Save theffc/fafff463bc7ad5de2c1b to your computer and use it in GitHub Desktop.
This is an edited piece of Linux Coding Style that shows why and when you should use typedefs.

Typedefs

It's a mistake to use typedef for structures and pointers. When you see a

vps_t a;

in the source, what does it mean?

In contrast, if it says

struct virtual_container *a;

you can actually tell what "a" is.

Lots of people think that typedefs "help readability". Not so. They are useful only for:

  • (a) totally opaque objects (where the typedef is actively used to hide what the object is).

    Example: "pte_t" etc. opaque objects that you can only access using the proper accessor functions.

    NOTE! Opaqueness and "accessor functions" are not good in themselves. The reason we have them for things like pte_t etc. is that there really is absolutely zero portably accessible information there.

  • (b) Clear integer types, where the abstraction helps avoid confusion whether it is "int" or "long".

    NOTE! Again - there needs to be a reason for this. If something is "unsigned long", then there's no reason to do:

    typedef unsigned long myflags_t;

    but if there is a clear reason for why it under certain circumstances might be an "unsigned int" and under other configurations might be "unsigned long", then by all means go ahead and use a typedef.

    u8/u16/u32 are perfectly fine typedefs, although they fit into category (d) better than here.

  • (c) when you use sparse to literally create a new type for type-checking.

  • (d) New types which are identical to standard C99 types, in certain exceptional circumstances.

    Although it would only take a short amount of time for the eyes and brain to become accustomed to the standard types like 'uint32_t', some people object to their use anyway.

    Therefore, the Linux-specific u8/u16/u32/u64 types and their signed equivalents which are identical to standard types are permitted -- although they are not mandatory in new code of your own.

    When editing existing code which already uses one or the other set of types, you should conform to the existing choices in that code.

  • (e) Types safe for use in userspace.

    In certain structures which are visible to userspace, we cannot require C99 types and cannot use the 'u32' form above. Thus, we use __u32 and similar types in all structures which are shared with userspace.

    Maybe there are other cases too, but the rule should basically be to NEVER EVER use a typedef unless you can clearly match one of those rules.

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

References

Linux Coding Style

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment