Question

Difference Between `struct Foo` and `typedef struct` in C++

cppstructtypedef

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
  • typedef struct { ... } Foo;
    • defines an unnamed struct and creates a typedef name Foo for it

In C++, both can often be used similarly afterward:

Foo x;

But they are not conceptually the same.

This matters because named types are easier to reference, forward-declare, document, and reuse in larger codebases. In modern C++, the direct named struct form is clearer and more idiomatic.

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.

Take Quiz

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:

  • Person is the actual name of the type
  • Product is a typedef name for an unnamed type

Modern C++ alias style

If you really want a type alias in modern C++, using is preferred over typedef:

struct Foo {
    int value;
};

using FooAlias = Foo;

This is clearer and works better for template aliases too.

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

  1. struct Foo { int value; };

    • A struct type is created.
    • Its name is Foo.
  2. typedef struct { int value; } Bar;

    • Another struct type is created.
    • This struct has no direct name.
    • Bar becomes a typedef name for that unnamed type.
  3. Foo a{10};

    • A variable a is created using the named type Foo.
  4. Bar b{20};

    • A variable b is created using the typedef alias Bar.

Important observation

Both variables work similarly when you create objects, but the types were declared differently. The first type has its own declared name. The second only has an 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.

Take Quiz

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:

struct Node;

This is useful in headers and large systems.

An anonymous struct in typedef struct { ... } Foo; cannot be forward-declared in the same direct way because the struct itself has no name.

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:

typedef struct {
    int x;
} Foo;

Prefer:

struct Foo {
    int x;
};

4. Forgetting that typedef does not create a new distinct type

A typedef is just another name for an existing type.

typedef int Score;

Score is still just int, not a brand-new type.

5. Missing the usefulness of named types for forward declarations

Broken design for large codebases:

typedef struct {
    int value;
} Foo;

You cannot separately forward-declare the anonymous struct type by name.

Better:

struct Foo;

struct Foo {
    int value;
};

Comparisons

FormMeaning in C++Has a real struct name?Needs typedef?Common in modern C++?
struct Foo { ... };Defines a struct type named FooYesNoYes
typedef struct { ... } Foo;Defines an unnamed struct and aliases it as FooNoYesRare
typedef struct Foo { ... } Foo;Defines a struct named Foo and also typedefs it as FooYesRedundant in C++Rare
using FooAlias = Foo;Creates an alias for an existing typeDepends on original typeNoYes

struct vs class

In C++, struct and class are almost the same. The main default difference is:

KeywordDefault member accessDefault inheritance
structpublicpublic
classprivateprivate

So this topic is about naming and aliasing types, not about object capability. A struct in C++ can have constructors, methods, operators, and private members too.

Take Quiz

Cheat Sheet

Quick rules

  • In C++, struct Foo { ... }; already creates a usable type name: Foo
  • typedef struct { ... } Foo; creates an anonymous struct plus alias Foo
  • In modern C++, prefer named structs directly
  • If you need an alias, prefer using over typedef

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

This is valid but redundant in C++:

typedef struct Foo {
    int x;
} Foo;

Because Foo was already a usable type name once the struct was declared.

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.

Take Quiz

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 using alias for one existing type
  • Construct at least one object of each type
  • Print the stored values to confirm they work as expected
Take Quiz

Keep learning

Related questions

View more