Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of struct, typedef struct, in C++

Tags:

c++

struct

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?

like image 666
dreadwail Avatar asked Jul 05 '09 12:07

dreadwail


2 Answers

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.

like image 180
Faisal Vali Avatar answered Sep 20 '22 14:09

Faisal Vali


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

like image 40
David Cournapeau Avatar answered Sep 18 '22 14:09

David Cournapeau