tags:

views:

1721

answers:

7

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?

A: 

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.

Simon
so its just less typing ?
darkrain
no need for 'struct' keyword in C++, only C
Joakim Elofsson
Ah sorry, always happens when C programmers get involved in C++ questions :(. But you caught the answer before I finished editing it :).
Simon
+5  A: 

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

anon
I really wish C++ would drop all the nasty things it has that were just there to keep it compatible with C in the beginning.
GMan
A: 

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
+8  A: 

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
in this case foo is also a unnamed struct
Joakim Elofsson
Right. and `MyStruct` will be used for linkage-purposes: You will find, for example, that the compiler will use it for mangling the names of member functions of it.
Johannes Schaub - litb
@David - yes - while typedef does create a usable name for the unnamed type, there are discernible consequences to the use of typedef - see my answer for details :)
Faisal Vali
A: 

There's no real difference in C++, you're right. It is for C compatibility though, structs are a bit different there, the structs live in their own "namespace" in C, so without a typedef you have to name it "struct MyStruct foo;" in C.

nos
+13  A: 

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
Wow! Thanks for this :)
Viet
Another difference would be in name mangling of functions within these structs or receiving them or pointers to them as parameters.
CesarB
@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
A: 

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.

David Rodríguez - dribeas