Beside Roberto's answer I want to go a little deeper on his point 1. This is one thing, where structs are more beneficial than typedefs.
When you use structure tags as references for pointers only, you can omit the forward declaration of the specific structure tag. The structure is incomplete and completed at its later following definition.
Related:
When you use a typedef instead, the alias needs to be defined before. This is a disadvantage.
Thus, This is completely valid (Proof):
Note that you can omit the typedefs here if you want to, as they are at least in this piece of code redundant. But if you use the, they don't conflict with the incomplete structure declarations as both reside in different namespaces and you need to use the struct keyword to symbolize the structure (tag).
#include <stdio.h>
typedef struct Color {
unsigned int red;
unsigned int green;
unsigned int blue;
} Color;
struct button {
char SizeUnit;
char Status;
int Width;
int Height;
char *Text;
struct Color TextColor;
struct Color BGColor;
struct Color BorderColor;
int BorderWidth;
void (*ActionL)(struct button *bt);
void (*ActionR)(struct button *bt);
void (*ActionM)(struct button *bt);
void (*Hover) (struct button *bt);
void (*draw) (struct button *bt);
} button;
I personally tend to not use typedefs at all. This is subject to:
struct button *? Because when the function pointer definitions are encountered, the typedef hasn't been encountered yet. (Or rather, is in the middle of being processed.)struct button *as mentioned by @Peter above, or declare the typedef first, like this:typedef struct button button;struct button { ... };.buttonA->draw(buttonB);Despite being called on objectbuttonA, it will indeed drawbuttonB. And a sensible callbuttonA->draw(buttonA);violates the don't-repeat-yourself rule.