开发者

Why often a struct's tagName differs from the typedef's name?

开发者 https://www.devze.com 2022-12-21 08:22 出处:网络
Sometimes I see code like this (I hope I remember it correctly): typedef struct st { int a; char b; } *stp;

Sometimes I see code like this (I hope I remember it correctly):

typedef struct st {
    int a; char b;
} *stp;

While the usual pattern that I familiar with, is:

t开发者_StackOverflow社区ypedef struct st {
    int a; char b;
} st;

So what's the advantage in the first code example?


You probably mean this:

typedef struct ST {
  /* fields omitted */
} *STP;

The asterisk is at the end of the statement. This simply means "define the type STP to be a pointer to a struct of this type". The struct tag (ST) is not needed, it's only useful if you want to be able to refer to the struct type by itself, later on.

You could also have both, like so:

typedef struct {
  /* fields omitted */
} ST, *STP;

This would make it possible to use ST to refer to the struct type itself, and STP for pointers to ST.

Personally I find it a very bad practice to include the asterisk in typedefs, since it tries to encode something (the fact that the type is a pointer) into the name of the type, when C already provides its own mechanism (the asterisk) to show this. It makes it very confusing and breaks the symmetry of the asterisk, which appears both in declaration and use of pointers.


It's a habit that stems from the time when typedef names and struct tagnames were in the same namespace. See http://blogs.msdn.com/oldnewthing/archive/2008/03/26/8336829.aspx


I think you are talking about :

typedef struct{
   int a;
   char b;
} object, *objectPointer;

This means that (new) type objectPointer is a pointer to struct (object) defined above. Its easy to declare pointers to object struct this way. For instance,

objectPointer A = (objectPointer)malloc(sizeof(object));
A->a = 2;

Now, A is a pointer to struct object and you can access its variables as described above.

In case, objectPointer was not defined,

struct object *A = (struct object *)malloc(sizeof(object));
A->a = 2;
So, I guess objectPointer is more intuitive and easy to use.


I hope that the first code would say a compiler error ,


I see no good reason for the typedef name be different from the tag name.

Now, the reason for which the tag name needs to be typedefed if you don't want to use

struct tag v;

but

tag v;

is probably an historical one. For as long as I remember, C had typedef but I don't know if it was true when struct have been introduced (handling of typedef is a nuisance in the C grammar). In the old code I've seen, using typedef for struct isn't done, and there are things like unix

struct stat;
int stat(const char*, struct stat*);

which would break with an automatic typedef. One those are introduced, changing is quite difficult (yes, C++ has automatic typedef but C++ has special wording to handle that case of overloading and it would be yet another complication).

0

精彩评论

暂无评论...
验证码 换一张
取 消