While researching queues in C, I came across an example similar to the below. Why is the struct named both at the beginning of the curly braces and after? Why is struct type used again inside of the struct when adding an item of the same type? Are these things redundant or is there a point?
typedef void* vpoint_t;
typedef struct queue_item_t{
vpoint_t void_item;
struct queue_item_t* next;
} queue_item_t;
You can't "typedef a struct", that doesn't mean anything.
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.
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.
You can declare a typedef name for a pointer to a structure or union type before you define the structure or union type, as long as the definition has the same visibility as the declaration. Typedef names can be used to improve code readability.
typedef struct queue_item_t { // 1
vpoint_t void_item;
struct queue_item_t* next; // 2
} queue_item_t; // 3
First of all, note that this entire statement is defining a typedef
.
3) Is saying that the new type we are in the process of defining (via typedef
) is going to be named queue_item_t
.
1) The name of the structure (which is being given a new name, as we go), is named struct queue_item_t
. That's it's full name, including struct
at the front.
2) Because the new type doesn't yet exist (remember, we're still in the process of defining it), we have to use the only name it has thus far, which is struct queue_item_t
, from 1).
Note that you can have anonymous struct
definitions, which allow you to omit the name from 1). A simple example:
typedef struct {
int x, y, z;
} vector3;
In your example however, since we need the structure to be able to refer to itself, the next
pointer must have a type that's already defined. We can do that by forward declaring the struct, typedefing it, then defining the struct using the typedef
d type for next
:
struct _queue_item; // 4
typedef struct _queue_item queue_item_t; // 5
struct _queue_item { // 6
vpoint_t void_item;
queue_item_t* next; // 7
}
4) Declare that struct _queue_item
exists, but don't yet provide a definition for it.
5) Typedef queue_item_t
to be the same as struct _queue_item
.
6) Give the definition of the structure now...
7) ...using our typedef
'd queue_item_t
.
All that being said... In my opinion, please don't use typedefs for structs.
struct queue_item {
void *data;
struct queue_item *next;
}
is simple and complete. You can manage to type those six extra characters.
From the Linux Kernel coding style:
Chapter 5: Typedefs
Please don't use things like "vps_t". It's a mistake to use typedef for structures and pointers. When you see a
vps_t a;
in the source, what does it mean? In contrast, if it says
struct virtual_container *a;
you can actually tell what "a" is.
There are exceptions, which you can read about.
Some recent related questions:
Why use an opaque “handle” that requires casting in a public API rather than a typesafe struct pointer?
Does casting a pointer back and forth from size_t or uintptr_t break strict aliasing?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With