40

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.

P.P
  • 117,907
  • 20
  • 175
  • 238

6 Answers6

60

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.

alexkr
  • 4,580
  • 1
  • 24
  • 21
29

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.

user438383
  • 5,716
  • 8
  • 28
  • 43
Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48
  • 7
    +1 for the observation that `typedef struct { ... } *obj` leads to a type that mysteriously requires `->` instead of `.` for element access. – Michael Oct 01 '15 at 02:54
  • 2
    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, – Neil Jul 02 '18 at 15:06
5

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.

Tobias Wärre
  • 793
  • 5
  • 11
  • 1
    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). – RastaJedi Sep 14 '16 at 04:24
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, ...;
Siva
  • 711
  • 1
  • 5
  • 8
1

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;
Dervin Thunk
  • 19,515
  • 28
  • 127
  • 217
FIFO
  • 11
  • 1
-1

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

Toad
  • 15,593
  • 16
  • 82
  • 128