typedef struct in C: Creating Custom Data Types

typedef struct in C: Creating Custom Data Types

C is famous for being explicit — and that includes how you define and refer to structured data. If you've ever written a struct and then felt mildly annoyed by repeating the word struct everywhere, you've already met the motivation for typedef struct in C.

This guide explains what typedef does, how typedef struct works, the difference between plain struct usage and typedef'd types, and when it improves readability versus when it can hide useful detail. You'll learn practical patterns, see real examples, and understand when to reach for typedef (and when to skip it).

What is typedef struct in C?

In C, a struct introduces a type, but the tag name isn't automatically a standalone "type alias" the way many people expect coming from other languages. The typedef keyword creates an alias for a type, letting you use cleaner syntax without repeating struct everywhere.

Think of it as a naming convenience: instead of writing struct User every time, you can just write User.

c typedef struct explained: the problem it solves

Without typedef, you have to use the full struct TagName syntax everywhere:

#include <stdio.h>

struct User {
  int id;
  const char *name;
};

int main(void) {
  struct User u = { .id = 1, .name = "Ada" };
  printf("%d %s\n", u.id, u.name);
  return 0;
}

Notice the repeated struct User. That's valid C, but it can feel noisy when used frequently — especially in larger codebases with many custom types.

how to use typedef with struct in c

typedef creates an alias for a type. When combined with struct, it allows you to use the type name without repeating struct everywhere:

#include <stdio.h>

typedef struct {
  int id;
  const char *name;
} User;

int main(void) {
  User u = { .id = 1, .name = "Ada" };
  printf("%d %s\n", u.id, u.name);
  return 0;
}

This is a common pattern: define the struct and immediately typedef it to a short, clean name like User. Much cleaner to read and write.

difference between struct and typedef struct

The key difference is naming and usage. Here's a comparison:

Syntax What it does Usage
struct User { ... }; Defines a struct type with tag User Used as struct User
typedef struct { ... } User; Defines anonymous struct and creates alias Used as User
typedef struct User { ... } User; Defines tagged struct AND creates alias Used as User (tag available for forward declarations)

Quick Reference: When to Use Which Pattern

Scenario Recommended Pattern
Simple data structure, no self-reference typedef struct { ... } Name;
Linked list, tree, or self-referential typedef struct Name { ... } Name;
Need forward declaration typedef struct Name Name; first
Opaque pointer (hiding implementation) typedef struct Name Name; (no definition in header)
Kernel/embedded code following style guides Often just struct Name { ... }; (no typedef)

Forward declaration use case

Forward declarations matter when two types reference each other, or when you want to hide implementation details behind pointers (a common API design pattern).

typedef struct Node Node;

struct Node {
  int value;
  Node *next;
}

Here, Node can be used before the full struct definition is complete. This is essential for self-referential data structures.

typedef struct example c: building a small data model

Example: a tiny linked list node

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
  int value;
  struct Node *next;
} Node;

int main(void) {
  Node *a = malloc(sizeof(Node));
  Node *b = malloc(sizeof(Node));

  if (!a || !b) {
    fprintf(stderr, "Allocation failed\n");
    return 1;
  }

  a->value = 1;
  a->next = b;

  b->value = 2;
  b->next = NULL;

  for (Node *cur = a; cur != NULL; cur = cur->next) {
    printf("%d\n", cur->value);
  }

  free(b);
  free(a);
  return 0;
}

This pattern uses typedef for readability while still keeping the tagged struct Node available for self-referential pointers.

Example: opaque type for API design

One powerful pattern is the opaque pointer — where you expose only a typedef in your header, hiding the actual structure definition in your implementation file:

database.h (header file):

typedef struct Database Database;

Database* db_open(const char *path);
void db_close(Database *db);
int db_query(Database *db, const char *sql);

database.c (implementation file):

#include "database.h"
#include <stdlib.h>

struct Database {
  void *internal_handle;
  int connection_count;
  // ... implementation details users don't need to see
};

Database* db_open(const char *path) {
  Database *db = malloc(sizeof(Database));
  // ... initialization
  return db;
}

Users of your API can pass around Database* pointers without knowing (or needing to know) the internal structure. This is how many C libraries maintain clean APIs and ABI stability.

why use typedef struct?

Used well, typedef struct can:

  • Reduce visual noise in codebases that use structs heavily
  • Encourage treating structs as "first-class types" (especially in APIs)
  • Make function signatures and data models easier to scan
  • Enable opaque types for better encapsulation and ABI stability
  • Make code feel more natural if you're coming from C++ or other languages

It's especially common in C libraries where the public API wants to look clean and intentional. Think of libraries like FILE from stdio.h — you use FILE*, not struct _IO_FILE*.

When NOT to use typedef struct

Not everyone loves typedef struct. Some codebases explicitly avoid it:

  • Linux kernel style: The kernel coding style discourages typedef for structures, preferring explicit struct everywhere to make the type system visible
  • Embedded systems: Some embedded style guides prefer clarity over brevity
  • Teaching code: Being explicit with struct helps learners understand what's happening
  • When debugging: Struct tags can be more visible in debuggers than typedef aliases

The choice often comes down to team conventions and project requirements.

Common mistakes and pitfalls to avoid

1) Over-typedef'ing everything

Typedef is not a free win. If it hides important information (like pointer-ness), it can reduce clarity.

For example, this is controversial:

typedef char* String;

Now the fact that it's a pointer (and needs careful memory handling) is hidden behind a friendly name. Struct typedefs are usually a better fit than pointer typedefs for readability. Most style guides suggest: typedef the struct, not the pointer.

2) Anonymous structs everywhere

Anonymous structs with typedef are fine, but named structs become valuable for forward declarations and debugging. Pick the pattern that fits your usage — if you need forward declarations or self-references, use the tagged version.

3) Confusing "type name" and "tag name"

In C, struct Thing and Thing can be different unless you typedef them. Keeping this mental model clear prevents head-scratching compiler errors. The struct tag lives in the "struct namespace" while the typedef lives in the "ordinary identifier namespace".

4) Forgetting sizeof still works the same

Whether you write sizeof(struct User) or sizeof(User), the result is identical. The typedef doesn't change memory layout or size — it's purely a naming convenience.

Related concepts and further reading

Official Documentation

Style Guides

Advanced Topics

Conclusion

typedef struct is one of those "tiny ergonomics" features that can make a C codebase feel calmer and more consistent — especially once your project has real data models. Use it deliberately, keep names descriptive, and don't be afraid to retain a tagged struct when forward declarations or self-references matter.

The best approach? Follow your project's conventions. If you're writing a library, consider opaque types for clean APIs. If you're working on embedded systems or kernel code, maybe stick with explicit struct. And if you're building application code where readability matters, typedef struct can make your data types feel more natural.

Explore more: C developer t-shirts

Wear the code

Product mockup

typedef struct Developer T-Shirt (C Edition — Dark Mode)

£25.00

View product
Product mockup

typedef struct Developer T-Shirt (C Edition — Light Mode)

£25.00

View product

0 comments

Leave a comment

Please note, comments need to be approved before they are published.