Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typedef a struct to a point with the same name as the struct

Tags:

c

gcc

struct

I ran across some C code from a legacy code base that has me scratching my head.

The code has typedef'd structs like the following all over the place.

typedef struct Foo {
    char *data;
    int  stuff;
} *Foo;

This compiles fine with GCC.

My question is what is the purpose of typedef'ing a struct to a struct pointer? Was this standard practice years ago? Is there something that I am missing? It seems like really bad style as it is obfuscating the struct pointer. Any help in understanding this legacy code would be greatly appreciated.

like image 341
Shane Avatar asked Dec 08 '22 11:12

Shane


2 Answers

It is not immediately what your question is about. Is it specifically about the names being the same? Or is it about hiding pointer types behind typedef names in general?

The first part is really a non-issue, since a struct Foo declaration in C language does not introduce name Foo. Foo is a so called struct tag, which cannot be used by itself. The full type name introduced by struct Foo declaration is struct Foo, i.e. both struct and Foo are required to form the full name of the type. Typedefing this struct Foo to a shorter typename Foo, which can be used by itself, is a widespread and rather useful practice. There's nothing unusual about it and there's nothing tricky about the fact that spelling of the typename coincides with the spelling of struct tag. E.g. this would be perfectly fine

typedef struct Foo {
    char *data;
    int  stuff;
} Foo;

struct Foo f1;  /* <- declares a `struct Foo` object */
Foo f2;         /* <- also declares a `struct Foo` object */
struct Foo *f3; /* <- declares a pointer to `struct Foo` */
Foo *f4;        /* <- also declares a pointer to `struct Foo` */

As for hiding pointer types behind typedef names... It is a controversial practice frowned upon by many, even when the typedef name is different from the struct tag. I personally prefer to avoid doing such things. And using a typename that coincides with the struct tag name for designating a pointer type (as in your example) makes it even worse. If you really want to do that, give the typedef name distinctive spelling, as in

typedef struct Foo {
    char *data;
    int  stuff;
} *FooPtr;

FooPtr f5; /* <- declares a pointer to `struct Foo` */

But again, obscuring the fact that a pointer type is a pointer type by hiding the * behind a new typename feels like something that will negatively impact readability of the code. Things like that might work well when there's a need to create an "opaque" type, a "handle" of some sort, whose pointer nature is completely inconsequential. But with regular pointers it is best to avoid doing something like that.

like image 64
AnT Avatar answered Mar 03 '23 16:03

AnT


Was this standard practice years ago?

Not as far as I know: it was far more typical to typedef the struct to its tag name, but not to a struct pointer.

Is there something that I am missing? It seems like really bad style as it is obfuscating the struct pointer.

You are absolutely right: a typedef like this is very likely to confuse your readers.

like image 30
Sergey Kalinichenko Avatar answered Mar 03 '23 18:03

Sergey Kalinichenko