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;
}
Answer from David Rodríguez - dribeas on Stack OverflowThe 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;
}
struct and typedef are two very different things.
The struct keyword is used to define, or to refer to, a structure type. For example, this:
struct foo {
int n;
};
creates a new type called struct foo. The name foo is a tag; it's meaningful only when it's immediately preceded by the struct keyword, because tags and other identifiers are in distinct name spaces. (This is similar to, but much more restricted than, the C++ concept of namespaces.)
A typedef, in spite of the name, does not define a new type; it merely creates a new name for an existing type. For example, given:
typedef int my_int;
my_int is a new name for int; my_int and int are exactly the same type. Similarly, given the struct definition above, you can write:
typedef struct foo foo;
The type already has a name, struct foo. The typedef declaration gives the same type a new name, foo.
The syntax allows you to combine a struct and typedef into a single declaration:
typedef struct bar {
int n;
} bar;
This is a common idiom. Now you can refer to this structure type either as struct bar or just as bar.
Note that the typedef name doesn't become visible until the end of the declaration. If the structure contains a pointer to itself, you have use the struct version to refer to it:
typedef struct node {
int data;
struct node *next; /* can't use just "node *next" here */
} node;
Some programmers will use distinct identifiers for the struct tag and for the typedef name. In my opinion, there's no good reason for that; using the same name is perfectly legal and makes it clearer that they're the same type. If you must use different identifiers, at least use a consistent convention:
typedef struct node_s {
/* ... */
} node;
(Personally, I prefer to omit the typedef and refer to the type as struct bar. The typedef saves a little typing, but it hides the fact that it's a structure type. If you want the type to be opaque, this can be a good thing. If client code is going to be referring to the member n by name, then it's not opaque; it's visibly a structure, and in my opinion it makes sense to refer to it as a structure. But plenty of smart programmers disagree with me on this point. Be prepared to read and understand code written either way.)
(C++ has different rules. Given a declaration of struct blah, you can refer to the type as just blah, even without a typedef. Using a typedef might make your C code a little more C++-like -- if you think that's a good thing.)
What is the point of typedef struct in C++?
How to use the typedef struct in C?
Is it bad to use typedef?
Difference between typedef struct and struct when manipulating it from within a function?
Videos
I am confused as to what to use when. Here are two examples:
typedef struct { data } name;
struct name { data };
Up to now I have just used the typedef one as some sort of mini Class replacement. ( I come from an OOP backround and it's great to bundle some data. )
But can I use the normal struct the same way? Does it have a different application?
Thanks :)
I understand that struct is useful in C due to the fact that there are no classes and having typedef struct means you don't have to explicitly write the struct keyword when declaring a variable based on the struct type. However what I don't understand is why do people still use typedef struct in C++ when first, there are already classes in C++ and secondly you don't need the struct keyword to define a variable with that struct type. Now I am saying this because I am looking at the Doom 3 BFG source code and they use a lot of typedef struct for data classes.