[c] typedef struct vs struct definitions

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;

This question is related to c struct typedef

The answer is


In C, the type specifier keywords of structures, unions and enumerations are mandatory, ie you always have to prefix the type's name (its tag) with struct, union or enum when referring to the type.

You can get rid of the keywords by using a typedef, which is a form of information hiding as the actual type of an object will no longer be visible when declaring it.

It is therefore recommended (see eg the Linux kernel coding style guide, Chapter 5) to only do this when you actually want to hide this information and not just to save a few keystrokes.

An example of when you should use a typedef would be an opaque type which is only ever used with corresponding accessor functions/macros.


The following code creates an anonymous struct with the alias myStruct:

typedef struct{
    int one;
    int two;
} myStruct;

You can't refer it without the alias because you don't specify an identifier for the structure.


The difference comes in when you use the struct.

The first way you have to do:

struct myStruct aName;

The second way allows you to remove the keyword struct.

myStruct aName;

Another difference not pointed out is that giving the struct a name (i.e. struct myStruct) also enables you to provide forward declarations of the struct. So in some other file, you could write:

struct myStruct;
void doit(struct myStruct *ptr);

without having to have access to the definition. What I recommend is you combine your two examples:

typedef struct myStruct{
    int one;
    int two;
} myStruct;

This gives you the convenience of the more concise typedef name but still allows you to use the full struct name if you need.


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


The typedef, as it is with other constructs, is used to give a data type a new name. In this case it is mostly done in order to make the code cleaner:

struct myStruct blah;

vs.

myStruct blah;

In C (not C++), you have to declare struct variables like:

struct myStruct myVariable;

In order to be able to use myStruct myVariable; instead, you can typedef the struct:

typedef struct myStruct someStruct;
someStruct myVariable;

You can combine struct definition and typedefs it in a single statement which declares an anonymous struct and typedefs it.

typedef struct { ... } myStruct;

You can't use forward declaration with the typedef struct.

The struct itself is an anonymous type, so you don't have an actual name to forward declare.

typedef struct{
    int one;
    int two;
} myStruct;

A forward declaration like this won't work:

struct myStruct; //forward declaration fails

void blah(myStruct* pStruct);

//error C2371: 'myStruct' : redefinition; different basic types

With the latter example you omit the struct keyword when using the structure. So everywhere in your code, you can write :

myStruct a;

instead of

struct myStruct a;

This save some typing, and might be more readable, but this is a matter of taste


If you use struct without typedef, you'll always have to write

struct mystruct myvar;

It's illegal to write

mystruct myvar;

If you use the typedef you don't need the struct prefix anymore.


I see some clarification is in order on this. C and C++ do not define types differently. C++ was originally nothing more than an additional set of includes on top of C.

The problem that virtually all C/C++ developers have today, is a) universities are no longer teaching the fundamentals, and b) people don't understand the difference between a definition and a declaration.

The only reason such declarations and definitions exist is so that the linker can calculate address offsets to the fields in the structure. This is why most people get away with code that is actually written incorrectly-- because the compiler is able to determine addressing. The problem arises when someone tries to do something advance, like a queue, or a linked list, or piggying-backing an O/S structure.

A declaration begins with 'struct', a definition begins with 'typedef'.

Further, a struct has a forward declaration label, and a defined label. Most people don't know this and use the forward declaration label as a define label.

Wrong:

struct myStruct
   {
   int field_1;
   ...
   };

They've just used the forward declaration to label the structure-- so now the compiler is aware of it-- but it isn't an actual defined type. The compiler can calculate the addressing-- but this isn't how it was intended to be used, for reasons I will show momentarily.

People who use this form of declaration, must always put 'struct' in practicly every reference to it-- because it isn't an offical new type.

Instead, any structure that does not reference itself, should be declared and defined this way only:

typedef struct
   {
   field_1;
   ...
   }myStruct;

Now it's an actual type, and when used you can use at as 'myStruct' without having to prepend it with the word 'struct'.

If you want a pointer variable to that structure, then include a secondary label:

typedef struct
   {
   field_1;
   ...
   }myStruct,*myStructP;

Now you have a pointer variable to that structure, custom to it.

FORWARD DECLARATION--

Now, here's the fancy stuff, how the forward declaration works. If you want to create a type that refers to itself, like a linked list or queue element, you have to use a forward declaration. The compiler doesn't consider the structure defined until it gets to the semicolon at the very end, so it's just declared before that point.

typedef struct myStructElement
   {
   myStructElement*  nextSE;
   field_1;
   ...
   }myStruct;

Now, the compiler knows that although it doesn't know what the whole type is yet, it can still reference it using the forward reference.

Please declare and typedef your structures correctly. There's actually a reason.


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to struct

How to search for an element in a golang slice "error: assignment to expression with array type error" when I assign a struct field (C) How to set default values in Go structs How to check for an empty struct? error: expected primary-expression before ')' token (C) Init array of structs in Go How to print struct variables in console? Why Choose Struct Over Class? How to return a struct from a function in C++? Initializing array of structures

Examples related to typedef

How do I use typedef and typedef enum in C? Overloading operators in typedef structs (c++) What is the difference between 'typedef' and 'using' in C++11? typedef fixed length array Typedef function pointer? C++ template typedef dereferencing pointer to incomplete type uint8_t vs unsigned char typedef struct vs struct definitions Understanding typedefs for function pointers in C