15

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?

dreadwail
  • 15,098
  • 21
  • 65
  • 96
  • 2
    This is a duplicate of http://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c, but I'm not going to vote for closure because the accepted answer to that question is (subtly) wrong, as explained in the second-voted answer... – Steve Jessop Jul 05 '09 at 12:27

6 Answers6

23

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.

Faisal Vali
  • 32,723
  • 8
  • 42
  • 45
  • Another difference would be in name mangling of functions within these structs or receiving them or pointers to them as parameters. – CesarB Jul 07 '09 at 16:38
  • @CesarB - well per the standard the typedef name does get used for linkage purposes if no other name is provided - so i don't see how it is different - perhaps you can provide an example? – Faisal Vali Jul 07 '09 at 16:43
12

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).

David Cournapeau
  • 78,318
  • 8
  • 63
  • 70
7

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

2

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.

Cromulent
  • 3,788
  • 4
  • 31
  • 41
  • Ah sorry, always happens when C programmers get involved in C++ questions :(. But you caught the answer before I finished editing it :). – Cromulent Jul 05 '09 at 12:19
0

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;
Nik
  • 1,364
  • 8
  • 7
0

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.

Community
  • 1
  • 1
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489