Difference Between 'Struct' and 'Typedef Struct' in C++

typedef struct vs struct definitions [duplicate]

The common idiom is using both:

typedef struct S { 
int x;
} S;

They are different definitions. To make the discussion clearer I will split the sentence:

struct S { 
int x;
};

typedef struct S S;

In the first line you are defining the identifier S within the struct name space (not in the C++ sense). You can use it and define variables or function arguments of the newly defined type by defining the type of the argument as struct S:

void f( struct S argument ); // struct is required here

The second line adds a type alias S in the global name space and thus allows you to just write:

void f( S argument ); // struct keyword no longer needed

Note that since both identifier name spaces are different, defining S both in the structs and global spaces is not an error, as it is not redefining the same identifier, but rather creating a different identifier in a different place.

To make the difference clearer:

typedef struct S { 
int x;
} T;

void S() { } // correct

//void T() {} // error: symbol T already defined as an alias to 'struct S'

You can define a function with the same name of the struct as the identifiers are kept in different spaces, but you cannot define a function with the same name as a typedef as those identifiers collide.

In C++, it is slightly different as the rules to locate a symbol have changed subtly. C++ still keeps the two different identifier spaces, but unlike in C, when you only define the symbol within the class identifier space, you are not required to provide the struct/class keyword:

 // C++
struct S {
int x;
}; // S defined as a class

void f( S a ); // correct: struct is optional

What changes are the search rules, not where the identifiers are defined. The compiler will search the global identifier table and after S has not been found it will search for S within the class identifiers.

The code presented before behaves in the same way:

typedef struct S { 
int x;
} T;

void S() {} // correct [*]

//void T() {} // error: symbol T already defined as an alias to 'struct S'

After the definition of the S function in the second line, the struct S cannot be resolved automatically by the compiler, and to create an object or define an argument of that type you must fall back to including the struct keyword:

// previous code here...
int main() {
S();
struct S s;
}

What is the real difference between struct and typedef struct in C?

There is no difference, typedef just removes the requirement to prefix variable declarations with struct.

Whether or not to typedef structs by default is a religious war fought mostly by people with too much time on their hands. When working inside an existing code base you should do whatever the coding standard or the surrounding code does. For your own personal code do whatever you prefer.

Difference between 'struct' and 'typedef struct' in C++?

In C++, there is only a subtle difference. It's a holdover from C, in which it makes a difference.

The C language standard (C89 §3.1.2.3, C99 §6.2.3, and C11 §6.2.3) mandates separate namespaces for different categories of identifiers, including tag identifiers (for struct/union/enum) and ordinary identifiers (for typedef and other identifiers).

If you just said:

struct Foo { ... };
Foo x;

you would get a compiler error, because Foo is only defined in the tag namespace.

You'd have to declare it as:

struct Foo x;

Any time you want to refer to a Foo, you'd always have to call it a struct Foo. This gets annoying fast, so you can add a typedef:

struct Foo { ... };
typedef struct Foo Foo;

Now struct Foo (in the tag namespace) and just plain Foo (in the ordinary identifier namespace) both refer to the same thing, and you can freely declare objects of type Foo without the struct keyword.


The construct:

typedef struct Foo { ... } Foo;

is just an abbreviation for the declaration and typedef.


Finally,

typedef struct { ... } Foo;

declares an anonymous structure and creates a typedef for it. Thus, with this construct, it doesn't have a name in the tag namespace, only a name in the typedef namespace. This means it also cannot be forward-declared. If you want to make a forward declaration, you have to give it a name in the tag namespace.


In C++, all struct/union/enum/class declarations act like they are implicitly typedef'ed, as long as the name is not hidden by another declaration with the same name. See Michael Burr's answer for the full details.

What's the difference between struct and typedef struct? [duplicate]

In this declaration

struct Structure {
char * name;
int number;
};

there is declared a type specifier struct Structure. Using it in declarations you have to write the keyword struct like

struct Structure s;

You may introduce a variable name Structure and it will not conflict with the the structure tag name because they are in different name spaces.

In this declaration

typedef struct {
char * name;
int number;
} Structure;

there is declared an unnamed structure for which there is introduced an alias Structure. You may not introduce the same name Structure for a variable in the same scope where the structure is defined.

Typedef struct vs struct? |Definition difference|

My question is why typedef needs flight to be written a second time at the end of a block?

When you declare:

typedef struct flight{
int number;
int capacity;
int passengers;
}flight;

you actually declare two things:

  • a new structure type struct flight
  • a type alias name flight for struct flight.

The reason why the type alias name with typedef appears at the end of the declaration like for any ordinary declaration is because for historical reasons typedef was put in the same specifiers category as storage-class specifiers (like static or auto).

Note that you can just declare:

typedef struct {
int number;
int capacity;
int passengers;
}flight;

without the tag name if you intend to only use the type identifier flight.

What is the difference between these two structure declarations?

With the first you can use either the type-alias COMPLEX or struct complex.

With the second you have an anonymous structure which can only be used with the type-alias COMPLEX.

With that said, in C++ any structure name is also a type-name and can be used as a type directly:

struct complex { ... };
complex c1;

Why should we typedef a struct so often in C?

As Greg Hewgill said, the typedef means you no longer have to write struct all over the place. That not only saves keystrokes, it also can make the code cleaner since it provides a smidgen more abstraction.

Stuff like

typedef struct {
int x, y;
} Point;

Point point_new(int x, int y)
{
Point a;
a.x = x;
a.y = y;
return a;
}

becomes cleaner when you don't need to see the "struct" keyword all over the place, it looks more as if there really is a type called "Point" in your language. Which, after the typedef, is the case I guess.

Also note that while your example (and mine) omitted naming the struct itself, actually naming it is also useful for when you want to provide an opaque type. Then you'd have code like this in the header, for instance:

typedef struct Point Point;

Point * point_new(int x, int y);

and then provide the struct definition in the implementation file:

struct Point
{
int x, y;
};

Point * point_new(int x, int y)
{
Point *p;
if((p = malloc(sizeof *p)) != NULL)
{
p->x = x;
p->y = y;
}
return p;
}

In this latter case, you cannot return the Point by value, since its definition is hidden from users of the header file. This is a technique used widely in GTK+, for instance.

UPDATE Note that there are also highly-regarded C projects where this use of typedef to hide struct is considered a bad idea, the Linux kernel is probably the most well-known such project. See Chapter 5 of The Linux Kernel CodingStyle document for Linus' angry words. :) My point is that the "should" in the question is perhaps not set in stone, after all.

How does the typedef struct work syntactically?

The typedef statement allows you to make an alias for the given type. You can then use either the alias or the original type name to declare a variable of that type.

typedef int number;

This creates an alias for int called number. So the following two statements declare variables of the same type:

int num1;
number num2;

Now using your example:

typedef struct {
char pseudo[MAX_SIZE] ;
int nb_mar ;
} player ;

This creates an anonymous struct and gives it the alias player. Because the struct doesn't have name, you can only use the alias to create a variable of that type.

struct set_of_players {
player T[NB_MAX_JOUEURS] ;
int nb ;
};

This creates a struct named struct set_of_players, but does not declare a typedef nor does it declare a variable of that type. Also notice that one of the fields is an array of type player, which we defined earlier. You can later declare a variable of this type as follows:

struct set_of_players my_set_var;

This line:

typedef struct set_of_players players;

Creates an alias for struct set_of_players called players. In this case the struct is not defined at the same time as the typedef but is defined elsewhere. So now you can declare a variable of this type like this:

players my_set_var;

Which is the same as the version using the full struct name.



Related Topics



Leave a reply



Submit