Question
I'm a beginner in C programming and I want to understand the difference between defining a structure with typedef and defining it without typedef.
These two examples seem to achieve the same result:
struct myStruct {
int one;
int two;
};
and
typedef struct {
int one;
int two;
} myStruct;
What is the actual difference between these two forms in C, and when would you use one over the other?
Short Answer
By the end of this page, you'll understand what a struct tag is in C, what typedef does, and why these two declarations look similar but are not exactly the same. You'll also learn the syntax developers use in real C codebases and how to choose the right form for readability and maintainability.
Concept
In C, struct and typedef solve related but different problems.
structdefines a structure type.typedefcreates an alias name for an existing type.
That means these are not identical operations.
1. Defining a struct without typedef
struct myStruct {
int one;
int two;
};
This creates a structure type with the tag myStruct.
To declare variables of that type, you must write:
struct myStruct a;
Notice that in C, the word struct is part of the type name when you use the tag.
2. Defining a struct with typedef
typedef struct {
int one;
int two;
} myStruct;
This creates an anonymous struct (a struct with no tag) and then gives it a typedef alias called myStruct.
Now you can declare variables like this:
myStruct a;
You do not write struct myStruct a; here, because myStruct is now a typedef name, not a struct tag.
Why this matters
The main difference is how you refer to the type later.
- With a plain struct tag: use
struct myStruct - With a typedef alias: use
myStruct
This matters in real programming because type names appear everywhere:
- function parameters
- return types
- pointers
- arrays
- API definitions
- header files
A shorter, cleaner type name can make code easier to read. But using plain struct is also common, especially in traditional C code and codebases that want to make it explicit that the type is a structure.
Important: these two forms are not exactly equivalent
Your two examples are close in purpose, but not the same in meaning.
First version
struct myStruct {
int one;
int two;
};
- Defines a struct tag:
myStruct - Usable as
struct myStruct - Does not create a typedef alias
Second version
typedef struct {
int one;
int two;
} myStruct;
- Defines an anonymous struct
- Creates a typedef alias:
myStruct - Usable as
myStruct - There is no struct tag named
myStruct
So this would be invalid for the second version:
struct myStruct x; // error: no struct tag named myStruct
A very common combined form
In C, you will often see this:
typedef struct myStruct {
int one;
int two;
} myStruct;
This creates both:
- a struct tag:
struct myStruct - a typedef alias:
myStruct
Then both of these work:
struct myStruct a;
myStruct b;
This pattern is common in headers and library code because it gives flexibility.
Why developers use typedef
Common reasons:
- Less typing
- Cleaner function signatures
- More readable public APIs
- Consistent style with other typedef-based types
Common reasons not to use it:
- It can hide that a type is a struct
- Some C programmers prefer explicitness
- Traditional C style often keeps
structvisible
So the choice is often partly about style, but the language-level difference is still real: one creates a tag, the other creates a type alias.
Mental Model
Think of struct and typedef like a person and a nickname.
struct myStructis the person's full formal name.typedef ... myStructis giving that type a shorter nickname.
If you only create the formal name, you must always use the full name:
struct myStruct x;
If you only create the nickname, you use the nickname:
myStruct x;
If you create both, you can use either one.
Another way to think about it:
structcreates the actual structure type definition.typedefcreates a label you can use instead of the original type spelling.
typedef does not create a new kind of data by itself. It only gives an existing type another name.
Syntax and Examples
Core syntax
Struct with a tag only
struct Point {
int x;
int y;
};
struct Point p1;
Here, Point is a struct tag. You must write struct Point when declaring variables.
Typedef with an anonymous struct
typedef struct {
int x;
int y;
} Point;
Point p1;
Here, Point is a typedef alias. You use Point directly.
Typedef with a tagged struct
typedef struct Point {
int x;
int y;
} Point;
Point p1;
struct Point p2;
This gives you both forms.
Beginner-friendly example
#include <stdio.h>
typedef struct {
int one;
int two;
} MyStruct;
int main(void) {
MyStruct value;
value.one = 10;
value.two = 20;
printf("%d %d\n", value.one, value.two);
return 0;
}
What this does
- Defines a struct type with two integer fields
- Creates the alias
MyStruct - Declares a variable named
value - Assigns values to the fields
- Prints them
Equivalent idea without typedef
#include <stdio.h>
struct MyStruct {
int one;
int two;
};
int main(void) {
struct MyStruct value;
value.one = 10;
value.two = 20;
printf("%d %d\n", value.one, value.two);
return 0;
}
This works the same at runtime. The difference is only in how the type is named in source code.
Step by Step Execution
Consider this example:
#include <stdio.h>
typedef struct {
int one;
int two;
} MyStruct;
int main(void) {
MyStruct a;
a.one = 5;
a.two = 7;
int total = a.one + a.two;
printf("%d\n", total);
return 0;
}
Step by step
1. The struct type is defined
typedef struct {
int one;
int two;
} MyStruct;
- A struct is defined with two members:
oneandtwo MyStructbecomes a typedef alias for that struct type
2. A variable is declared
MyStruct a;
- Memory is reserved for one struct variable named
a - It contains space for two
intfields
3. Field values are assigned
a.one = 5;
a.two = 7;
a.onestores5a.twostores7
4. The values are used
int total = a.one + a.two;
- Reads
a.one→5 - Reads
a.two→7 - Adds them to get
12 - Stores
12intotal
5. Output is printed
printf("%d\n", total);
- Prints
12
Same logic without typedef
The only source-code difference is the type name:
struct MyStruct {
int one;
int two;
};
int main(void) {
struct MyStruct a;
a.one = 5;
a.two = 7;
int total = a.one + a.two;
return 0;
}
Execution is effectively the same. The compiler just sees a different spelling of the type.
Real World Use Cases
Structures are used whenever you need to group related data together.
Common examples
User records
typedef struct {
int id;
char name[50];
} User;
Used in:
- command-line tools
- file parsing
- database-like records in memory
2D points or geometry
typedef struct {
int x;
int y;
} Point;
Used in:
- graphics programs
- games
- coordinate calculations
Configuration data
typedef struct {
int port;
int debug;
} Config;
Used in:
- application settings
- server startup options
- embedded systems
API response models
typedef struct {
int status;
char message[100];
} Response;
Used in:
- networking code
- protocol handling
- library interfaces
Where typedef helps in practice
If a type appears frequently in function signatures, a typedef can improve readability:
void print_user(User user);
int save_config(Config config);
Without typedef:
void print_user(struct User user);
int save_config(struct Config config);
Both are valid, but many programmers find the typedef form cleaner.
Real Codebase Usage
In real C projects, the choice between struct X and typedef struct ... X often depends on team style, API design, and compatibility needs.
Common patterns
1. Public data models in header files
Libraries often use typedefs so users of the library get simple names:
typedef struct {
int code;
char text[64];
} ErrorInfo;
This keeps function signatures short:
ErrorInfo get_last_error(void);
2. Opaque structs for encapsulation
A common C pattern is to expose only a forward declaration in a header:
typedef struct FileHandle FileHandle;
The full struct definition is hidden in a .c file. This lets developers use pointers without seeing internal fields:
FileHandle *open_file(const char *path);
This is very common in libraries.
3. Self-referential structs
When a struct needs to refer to itself, a tag is useful:
typedef struct Node {
int value;
struct Node *next;
} Node;
Inside the definition, struct Node *next; uses the tag.
4. Validation and function boundaries
Structs are commonly passed to helper functions:
int is_valid_user(const User *user);
void print_user(const User *user);
Using typedef can make these signatures easier to scan.
5. Error handling and configuration objects
Large C programs often group related settings or status data into structs instead of passing many separate parameters.
int start_server(const Config *config);
This improves maintainability when requirements grow.
Common Mistakes
1. Thinking typedef creates a new struct kind
typedef does not create a brand new data structure. It only creates another name for a type.
typedef int Number;
Number is still just int.
The same idea applies to structs.
2. Mixing up tag names and typedef names
Broken example:
typedef struct {
int one;
int two;
} MyStruct;
struct MyStruct a; // wrong
Why it fails:
MyStructhere is a typedef alias- There is no struct tag named
MyStruct
Correct:
MyStruct a;
Or define both:
typedef struct MyStruct {
int one;
int two;
} MyStruct;
struct MyStruct a;
MyStruct b;
3. Forgetting struct when no typedef exists
Broken example:
struct Point {
int x;
int y;
};
Point p; // wrong in C
Correct:
struct Point p;
4. Confusing C with C++
In C++, you can usually write:
Point p;
after defining a struct. In C, that only works if you used typedef.
5. Using lowercase names that look like variables
This is valid:
typedef struct {
int one;
int two;
} myStruct;
But beginners may confuse myStruct the type with myStruct a variable. Many codebases use names like MyStruct or my_struct_t to make type names clearer.
6. Anonymous struct limitations
If you use an anonymous struct with typedef, you cannot refer to it later by a tag name because it has no tag.
typedef struct {
int value;
} Item;
This is fine unless you specifically need a struct tag, such as in some forward declaration or self-referential cases.
Comparisons
| Form | What it creates | How you declare a variable | Notes |
|---|---|---|---|
struct Point { ... }; | Struct tag Point | struct Point p; | Traditional C style |
typedef struct { ... } Point; | Typedef alias Point | Point p; | Anonymous struct with alias |
typedef struct Point { ... } Point; | Tag Point and typedef alias Point | struct Point p; or Point p; | Very common in real projects |
struct tag vs typedef alias
| Feature | Struct tag | Typedef alias |
|---|---|---|
| Purpose | Names a struct type in the tag namespace | Creates an alternate type name |
Requires struct keyword when used | Yes | No |
| Can exist without typedef | Yes | No |
| Useful for self-referential structs | Yes | Indirectly, but tag is usually needed |
Which should you choose?
| Situation | Common choice |
|---|---|
| Learning basic C syntax | struct Name |
| Cleaner API names | typedef |
| Opaque library handles | typedef struct Name Name; |
| Linked lists or trees | Tagged struct, often with typedef too |
| Strictly explicit code style | Plain struct |
Cheat Sheet
Quick rules
struct X { ... };defines a struct tag namedX- Use it as
struct X variable; typedef struct { ... } X;creates a typedef alias namedX- Use it as
X variable; typedef struct X { ... } X;gives you both forms
Common patterns
Tag only
struct Person {
int age;
};
struct Person p;
Typedef only
typedef struct {
int age;
} Person;
Person p;
Tag + typedef
typedef struct Person {
int age;
} Person;
Person p1;
struct Person p2;
Important edge case
This does not create a struct tag:
typedef struct {
int x;
} Point;
So this is invalid:
struct Point p;
Good rule of thumb
- Want explicit traditional C? Use
struct Name - Want shorter type names? Use
typedef - Want flexibility? Use both
FAQ
What is the difference between struct and typedef struct in C?
struct defines a structure type with a tag, while typedef gives a type another name. A plain struct must be used as struct Name, but a typedef alias can be used as Name.
Does typedef struct create a new type?
Not in the same sense as defining a new kind of data. It creates an alias for a type. The underlying struct type is still the same.
Why do C programmers often use typedef with structs?
Mostly for convenience and readability. It removes the need to write struct every time the type is used.
Can I use struct MyType after typedef struct { ... } MyType;?
No. That form creates a typedef alias but no struct tag named MyType.
When should I use typedef struct Name { ... } Name;?
Use it when you want both a struct tag and a short alias. This is common in larger C projects and libraries.
Is this different in C++?
Yes. In C++, struct type names can usually be used directly without typedef. In C, you need typedef if you want that shorter form.
Which style is more correct?
Both are correct. The best choice depends on your codebase style, readability goals, and whether you need a struct tag.
Mini Project
Description
Build a small C program that stores and prints information about a book. The goal is to practice defining a struct both conceptually and syntactically, and to see how a typedef makes declarations shorter in normal code.
Goal
Create a program that defines a Book structure, stores one book's data, and prints it using a function.
Requirements
- Define a structure with fields for title, author, and year.
- Use
typedefso the type can be written without thestructkeyword. - Create one variable of that type in
main. - Assign values to all fields.
- Write a function that accepts the struct and prints its contents.
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.