42

I had come across the following code:

typedef struct { double x; double y; double z; } *vector; 

Is this a valid type definition? The code compiles and runs fine. I was just curious if this is common practice.

6 Answers 6

63

Absolutely valid. Usually, you can take full advantage of this way by defining two types together:

typedef struct { int a; int b; } S1, *S1PTR; 

Where S1 is a struct and S1PTR is the pointer to this struct.

Sign up to request clarification or add additional context in comments.

2 Comments

...and maybe const *S1CPTR.
Just to confirm I understand. Is that equivalent to typedef struct {...} S1; typedef S1* S1PTR;?
30

Yes it is. But it is in my opininon bad style. Not the direct declaration of the struct, but the direct declaration of a pointer type. It is obfuscation, the information that a given variable or parameter is a pointer (and to a lesser extent for arrays) is extremely important when you want to read code.

When reviewing code it is often difficult to see at first glance which function could have a side effect or not. If the types used hide this information, it adds a memorisation burden to the reader.

int do_fancy(vector a, vector b); 

or

int do_fancy(vector *a, vector *b); 

in the first case I can miss easily that that function may change the content of a or b. In the second I'm warned.

And when actually writing code I also know directly to write a->x and not have the compiler tell me error: request for member x' in something not a structure or union`.

I know, it looks like a personal taste thing, but having worked with a lot of external code, I can assure you that it's extremely annoying when you do not recognize the indirection level of variables. That's one reason I also dislike C++ references (in Java it's not because all objects are passed by reference, it's consistent) and Microsoft's LPCSTR kind of types.

2 Comments

+1 for the observation that typedef struct { ... } *obj leads to a type that mysteriously requires -> instead of . for element access.
Strict naming conventions would inform user of the type of typedef, so not really bad style. However I see your point when working with external code using different coding practises,
6

Yes it is valid. If you need more "security" you can also do

typedef struct vector_{ double x; double y; double z; } *vector; 

then you can use both

struct vector_ *var; vector var; 

But don't forget the ending semi-colon.

Using only typedef means that you name it that way. otherwise it'd be more or less anonymous.

1 Comment

I believe you can use the same name for both (i.e., you don't need the underscore but can leave everything else in your code the same, because the namespaces are separate).
4

It a valid one, what it does is it defines a new type. As @Alex said, it would be useful to define a type and pointer type.

You could create more pointers just by using

S1PTR ptr1, ptr2, ptr3, ...; 

instead of

S1 *ptr1, *ptr2, *ptr3, ...; 

Comments

2

Yes it is valid as described in above answers. A small suggestion, it would be better if you provide a tag name too, as follows. This would help some IDEs to better parse your code.

typedef struct vactor_tag { double x; double y; double z; } *vector; 

Comments

-1

yes...saves you the trouble of constantly typing the word 'struct' everytime you declare the vector struct or a pointer to it.

1 Comment

I think the question had to do more with the typedef'ing to *vector rather than just vector.