dreadwail
dreadwail

Reputation: 15410

Purpose of struct, typedef struct, in C++

In C++ it is possible to create a struct:

struct MyStruct
{
    ...
}

And also possible to do the following:

typedef struct
{
    ...
} MyStruct;

And yet as far as I can tell, no discernable difference between the two. Which is preferable? Why do both ways exist if there is no difference? Is one better than the other in style or readability?

Upvotes: 15

Views: 14243

Answers (6)

Faisal Vali
Faisal Vali

Reputation: 33703

Here are the differences between the two declarations/definitions:


1) You cannot use a typedef name to identify a constructor or a destructor

struct MyStruct { MyStruct(); ~MyStruct(); }; // ok

typedef struct { MyStructTD(); ~MyStructTD(); } MyStructTD; // not ok

// now consider 
typedef struct MyStruct2 { MyStruct2(); } MyStructTD2; // ok

MyStructTD2::MyStruct2() { } // ok
MyStructTD2::MyStructTD2() { } // not ok

2) You cannot hide a typedef name like you can a name introduced via the class-head - or conversely if you already have a function or an object with a certain name, you can still declare a class with that name using the class-head but not via the typedef approach.

struct MyStruct { }; // ok

typedef struct { } MyStructTD; // ok

void MyStruct() { }  // (1) - ok Hides struct MyStruct
void MyStructTD() { }  // (2) - not-ok - ill-formed

//> Or if you flip it around, consider in a new translation unit:

void MyStruct() { }   // ok
void MyStructTD() { }   // ok

struct MyStruct { }; // ok
typedef struct { } MyStructTD; // Not ok

3) You cannot use a typedef name in an elaborated type specifier

struct MyStruct {  }; // ok

typedef struct { } MyStructTD; // ok

int main()
{
  void MyStruct(); 
  void MyStructTD(); // ok - new declarative region

  struct MyStruct ms; // ok - names the type
  struct MyStructTD ms2; // not ok - cannot use typedef-name here

}

struct AnotherStruct 
{ 
    friend struct MyStruct;  // ok
    friend struct MyStructTD; // not ok
};

4) You cannot use it to define nested structs

struct S { struct M; };

typedef struct { } S::M;  // not ok

struct S::M { }; // ok

As you can see, there is a discernible difference between the two. Some of the quirks of typedefs are a result of C compatibility (which is mainly why both ways exist i believe) - and in most cases, declaring the name in the class-head is more natural C++ - it has its advantages (especially when you need to define constructors and destructors), and is therefore preferable. If you are writing code that needs to be C and C++ compatible, then there is benefit to using both approaches. But if you are writing pure C++, I find specifying the class name in the class-head to be more readable.

Upvotes: 23

There are many answers that consider both approaches as equivalent, but they are not.

The typedef keyword is used to create a type alias, that is, it provides a new way of referring to another type. When you use typedef struct {} XXX; you are actually creating an unnamed type and then creating an alias XXX to that unnamed type. On the other hand, when you type struct XXX {}.

Please, read the answer by Michael Burr here (which is a better answer than the one accepted for that question.

Upvotes: 0

David Cournapeau
David Cournapeau

Reputation: 80770

The typedef version is a special case of

typedef foo bar;

which defines a new "type" bar as an alias for foo. In your case, foo happens to be a struct. In C, this was the only way to introduce new "types" (in quotes, because they are not really equivalent to int, float and co). In C++, this is not so useful, because C++ was designed to make definition of new types easier and more complete than C (at least at the beginnings of C++), and the typedef is not even necessary to refer to a previously declared struct (or class).

Upvotes: 12

Nik
Nik

Reputation: 1364

The "struct MyStruct { };" construct implicitly defines the equivalent typedef, so typically that would be the preferred modern usage. There are still some uses for a typedef, mainly with pointer types to structures. E.g.

typedef struct MyStruct* MyStructPtr;

Upvotes: 0

anon
anon

Reputation:

The latter is there for compatibility with C - use the first in new C++ code.

Upvotes: 7

Cromulent
Cromulent

Reputation: 3818

You would use a typedef so you do not need to specify the struct keyword when declaring variables of that struct.

Without typedef:

struct MyStruct foo;

With typedef:

MyStruct foo;

Basically you are making MyStruct appear as a new type so it also implements some level of type abstraction as programmers do not need to know explicitly what type it is. You can pass MyStruct into a function, manipulate the data in it and return it and the programmer need never worry about what actually happens.

Much of the C standard library uses typedefs for this reason.

Upvotes: 2

Related Questions