tags:

views:

96

answers:

5

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:

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

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

+1  A: 

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

abubacker
Indeed there was an error. See comments to my question.
Dor
+4  A: 

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.

unwind
`typedef` ing `*` is useful for opaque types, which might be implemented as pointers, but could have been implemented as numeric ids just as well; if done sensibly, information hiding through `typedef` is a good thing
Christoph
+2  A: 

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.

N 1.1
No, it means that something of type `object` is a pointer to `struct _object`.
Artelius
@Artelius: oh yes. I should clearly written type. thanks.
N 1.1
+1. In the first code: Does a semicolon omitted at the end of the struct? (line 4)
Dor
@Dor: yes. semicolon after struct.
N 1.1
+2  A: 

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

Artelius
Do you have another reference hinting that there was such a time? I'll try to dig out in DMR home page and some other old documentation I've. to confirm. I don't remember it. (What I remember was that the member namespace was unique for all struct and union, that explain the prefixes in members names of Unix structures).
AProgrammer
No, but I consider OldNewThing fairly reliable.
Artelius
Thanks, enjoyed reading the referenced post. +1
Dor
A: 

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

AProgrammer