Why is "typedef struct foo foo;" considered harmful?

The only downside(*) is that it hides the fact that foo is a struct, and not an alias for some builtin type.

Note(*): it's matter of taste whether this is a downside for you.

  • It's good for total opaqueness (see the first comment below).
  • To see why some people think this is a downside, check the linux kernel coding style (typedefs chapter).

On whether or not to typedef structure types:

Here is some opinions around (all against typedefing structures):

From OpenBSD style guide:

"Avoid using typedefs for structure types. This makes it impossible for applications to use pointers to such a structure opaquely, which is both possible and beneficial when using an ordinary struct tag."

From Linux kernel coding style:

"It's a mistake to use typedef for structures and pointers."

From Expert C Programming by Peter Van der Linden:

"Don't bother with typedefs for structs. All they do is save you writing the word "struct", which is a clue that you probably shouldn't be hiding anyway."


It depends how much you like the word struct. If you feel your program will be made clearer by a liberal sprinkling of struct that and struct tother (you can't have struct this in C++, of course), then by all means use the struct version.

Personally, I don't think that repeating struct provides any benefit and I'm happy to use just the typedef name. And because C++ effectively provides the typedef struct xyz xyz; declaration automatically (it isn't quite accurate, not least because you can explicitly write that in C++, but it is close enough that you probably don't have to worry about it), I think it makes perfect sense to use the same in C. The C compiler is happy with it, so I normally use typedef struct tag tag; and then use tag and tag * where needed.


For an alternative but wholly tenable view, read the Linux kernel coding style guide.


Note that C2011 allows you to redefine a typedef as long as it aliases the same type:

ISO/IEC 9899:2011 §6.7 Declarations

Semantics

¶5 A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:

— for an object, causes storage to be reserved for that object;

— for a function, includes the function body;119)

— for an enumeration constant, is the (only) declaration of the identifier;

— for a typedef name, is the first (or only) declaration of the identifier.

Contrast with C99 where this was not possible:

ISO/IEC 9899:1999 §6.7 Declarations

Semantics

¶5 A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:

— for an object, causes storage to be reserved for that object;

— for a function, includes the function body;98)

— for an enumeration constant or typedef name, is the (only) declaration of the identifier.

This simplifies the creation of type definitions as long as you're consistent (but only if you have a sufficiently compatible C2011 compiler on each platform of relevance to you).

Tags:

C

Coding Style