Question
In C++, is there any difference between these two declarations?
struct Foo {
// members...
};
and:
typedef struct {
// members...
} Foo;
If they are different, what does each form mean, and which style is preferred in modern C++?
Short Answer
By the end of this page, you will understand how struct names work in C++, what typedef struct { ... } Foo; actually creates, and why the first form is usually preferred in modern C++ code. You will also see how this differs from C-style usage and how developers typically write type aliases today.
Concept
In C++, struct defines a type. Unlike C, the name of the struct becomes a normal type name immediately.
That means this is enough:
struct Foo {
int value;
};
Foo x;
You do not need typedef just to use Foo as a type name.
Now compare that with:
typedef struct {
int value;
} Foo;
This creates an anonymous struct type and then gives that type the alias Foo using typedef.
So the main difference is:
struct Foo { ... };- defines a struct named
Foo
- defines a struct named
typedef struct { ... } Foo;- defines an unnamed struct and creates a typedef name
Foofor it
- defines an unnamed struct and creates a typedef name
In C++, both can often be used similarly afterward:
Mental Model
Think of a type like a person in a contact list.
struct Foo { ... };means the person is officially named Foo.typedef struct { ... } Foo;means the person has no original name, but you saved them in your phone as Foo.
In everyday use, you can still call them Foo, but internally the first one has a real declared type name, while the second is an unnamed type with an alias attached to it.
In C++, giving the type a real name directly is usually the cleaner choice.
Syntax and Examples
Core syntax
Named struct in C++
struct Foo {
int value;
};
Foo a;
This defines a type named Foo.
Anonymous struct with a typedef alias
typedef struct {
int value;
} Foo;
Foo a;
This defines an unnamed struct type and creates the alias Foo.
Example showing the practical difference
struct Person {
std::string name;
int age;
};
typedef struct {
std::string title;
double price;
} Product;
Person p{"Maya", 28};
Product item{"Notebook", 4.99};
Here:
Personis the actual name of the typeProductis a typedef name for an unnamed type
Modern C++ alias style
Step by Step Execution
Consider this example:
struct Foo {
int value;
};
typedef struct {
int value;
} Bar;
int main() {
Foo a{10};
Bar b{20};
}
What happens step by step
-
struct Foo { int value; };- A struct type is created.
- Its name is
Foo.
-
typedef struct { int value; } Bar;- Another struct type is created.
- This struct has no direct name.
Barbecomes a typedef name for that unnamed type.
-
Foo a{10};- A variable
ais created using the named typeFoo.
- A variable
-
Bar b{20};- A variable is created using the typedef alias .
Real World Use Cases
When you see struct Foo { ... };
This is the normal style in modern C++ for:
- data models
- configuration objects
- simple value types
- small helper types
- public API types
Example:
struct Config {
std::string host;
int port;
bool debug;
};
When you might see typedef struct { ... } Foo;
This is common in:
- old C code
- C headers written for C compatibility
- codebases that started in C and later included C++
- cross-language or legacy APIs
Example from C-style code:
typedef struct {
int x;
int y;
} Point;
In C, this pattern is useful because plain struct Foo and Foo are not automatically the same thing. In C++, that extra typedef is usually unnecessary.
Real Codebase Usage
In real C++ projects, developers usually prefer the named form:
struct User {
std::string email;
bool active;
};
Common reasons:
- easier to read
- easier to forward declare
- easier to document
- fits modern C++ style
Common patterns in codebases
1. Public data structures
struct Request {
std::string path;
std::string method;
};
2. Configuration objects
struct DatabaseOptions {
std::string host;
int port;
};
3. Type aliases with using
If a shorter or more meaningful alias is needed:
struct DatabaseOptions {
std::string host;
int port;
};
using DbOptions = DatabaseOptions;
4. Forward declarations
A named struct can be declared before its full definition:
Common Mistakes
1. Assuming C and C++ treat struct names the same way
Beginners often learn a C-style pattern and use it in C++ without knowing why.
C++
struct Foo {
int x;
};
Foo a; // valid
In C
struct Foo {
int x;
};
struct Foo a; // needed unless typedef is used
In C++, the struct name is already a usable type name.
2. Thinking typedef struct { ... } Foo; creates a struct named Foo
It does not.
typedef struct {
int x;
} Foo;
Here, the struct itself is unnamed. Foo is a typedef alias.
3. Using old C-style syntax in modern C++ without a reason
This is valid C++, but usually not the clearest style:
Comparisons
| Form | Meaning in C++ | Has a real struct name? | Needs typedef? | Common in modern C++? |
|---|---|---|---|---|
struct Foo { ... }; | Defines a struct type named Foo | Yes | No | Yes |
typedef struct { ... } Foo; | Defines an unnamed struct and aliases it as Foo | No | Yes | Rare |
typedef struct Foo { ... } Foo; | Defines a struct named Foo and also typedefs it as Foo | Yes | Redundant in C++ |
Cheat Sheet
Quick rules
- In C++,
struct Foo { ... };already creates a usable type name:Foo typedef struct { ... } Foo;creates an anonymous struct plus aliasFoo- In modern C++, prefer named structs directly
- If you need an alias, prefer
usingovertypedef
Common forms
struct Foo {
int x;
};
typedef struct {
int x;
} Foo;
using Alias = Foo;
Best practice
Prefer:
struct Foo {
int x;
};
Why
- clearer intent
- easier forward declarations
- more idiomatic C++
- avoids old C-style noise
Edge case
FAQ
Is typedef struct needed in C++?
No. In C++, a struct name is already a normal type name.
Are the two forms exactly equivalent?
Not exactly. They often behave similarly when creating variables, but one defines a named type and the other defines an unnamed type with an alias.
Which style should I use in modern C++?
Use struct Foo { ... }; in most cases. It is the clearer and more idiomatic form.
Why do I still see typedef struct in some code?
Usually because the code is old, written in C style, or intended to be compatible with C.
Can an anonymous struct typedef be forward-declared?
Not in the same simple way as a named struct, because the struct itself has no name.
Should I use typedef or using in modern C++?
Prefer using for new aliases. It is clearer and more flexible, especially with templates.
Is struct different from class here?
Not for naming. The main difference between struct and class in C++ is default access level, not whether the type is usable by name.
Mini Project
Description
Create a small C++ program that defines a few data types in different ways and prints their values. This helps you see the difference between a directly named struct and a typedef alias for an anonymous struct. It also introduces the modern using alias style.
Goal
Build a program that declares types with struct, typedef struct, and using, then creates objects from each and prints their contents.
Requirements
- Define one type using
struct Name { ... }; - Define one type using
typedef struct { ... } AliasName; - Create a
usingalias for one existing type - Construct at least one object of each type
- Print the stored values to confirm they work as expected
Keep learning
Related questions
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Base Class Constructor Rules Explained
Learn how C++ base class constructors are called from derived classes, including order, syntax, defaults, and common mistakes.
C++ Casts Explained: C-Style Cast vs static_cast vs dynamic_cast
Learn the difference between C-style casts, static_cast, and dynamic_cast in C++ with clear examples, safety rules, and real usage tips.