Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typedef struct vs struct definitions [duplicate]

Tags:

c

struct

typedef

I'm a beginner in C programming, but I was wondering what's the difference between using typedef when defining a structure versus not using typedef. It seems to me like there's really no difference, they accomplish the same goal.

struct myStruct{     int one;     int two; }; 

vs.

typedef struct{     int one;     int two; }myStruct; 
like image 428
user69514 Avatar asked Nov 04 '09 17:11

user69514


People also ask

What is difference between struct and typedef struct?

Basically struct is used to define a structure. But when we want to use it we have to use the struct keyword in C. If we use the typedef keyword, then a new name, we can use the struct by that name, without writing the struct keyword.

Is typedef struct bad in C?

typedef'ing structs is one of the greatest abuses of C, and has no place in well-written code. typedef is useful for de-obfuscating convoluted function pointer types and really serves no other useful purpose.

What is the advantage of using typedef with a structure?

Typedefs provide a level of abstraction away from the actual types being used, allowing you, the programmer, to focus more on the concept of just what a variable should mean. This makes it easier to write clean code, but it also makes it far easier to modify your code.

What does typedef struct mean?

The C language contains the typedef keyword to allow users to provide alternative names for the primitive (e.g.,​ int) and user-defined​ (e.g struct) data types. Remember, this keyword adds a new name for some existing data type but does not create a new type.


2 Answers

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; } 
like image 114
David Rodríguez - dribeas Avatar answered Oct 04 '22 15:10

David Rodríguez - dribeas


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

like image 45
Keith Thompson Avatar answered Oct 04 '22 15:10

Keith Thompson