0

I was browsing the libgphoto2 repositories and saw this:

struct _PTPObjectHandles {
    uint32_t n;
    uint32_t *Handler;
};
typedef struct _PTPObjectHandles PTPObjectHandles;

Why would somebody want do that instead of just calling the struct PTPObjectHandles and omitting the whole typedef line?

EDIT: I should probably note that _PTPObjectHandles is never again used in the code.

Matteo
  • 37,680
  • 11
  • 100
  • 115
iFreilicht
  • 13,271
  • 9
  • 43
  • 74
  • See [Why should we typedef a struct so often in C?](http://stackoverflow.com/a/252810/758831). `_PTPObjectHandles` is unlikely to be used in the code as the typedef will be used from then on (i.e. `PTPObjectHandles`) – wmorrison365 Apr 01 '14 at 13:35
  • 1
    Drive-by useless note: `_PTPObjectHandles` is not OK since names beginning with `_[A-Z]` are reserved. – cnicutar Apr 01 '14 at 13:40
  • 2
    @cnicutar: I was thinking of answering based on this. It's technically *undefined behaviour*. – Bathsheba Apr 01 '14 at 13:40
  • 1
    possible duplicate of [Why should we typedef a struct so often in C?](http://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c) – unwind Apr 01 '14 at 13:48
  • @unwind I know why typedef would make sense, but I didn't really get why you would need to first define a struct with a different name and **then** typedef that. – iFreilicht Apr 01 '14 at 14:37

4 Answers4

2

The most common reason for doing this is simply to make it shorter to type and begin to look like a "real data type".

EG, this:

struct _PTPObjectHandles *ptr1;
int something;
struct _PTPObjectHandles *ptr2;

Simply looks "cooler" if you rewrite it as:

PTPObjectHandles *ptr1;
int something;
PTPObjectHandles *ptr2;

That's the main reason.

However, it also provides the library developer that is making you use it the ability to re-typedef it as something else in the future. I've seen cases (eg, OpenSSL) that changed a typedef from a real struct to a pointer to a struct (for example). (Granted, that didn't work, but you can imagine the case where a typedef does actually change and it would work.)

So, do you have to? No.

Do people do it to try and make code more readable? Yes.

Note that a C++ class is actually doing about the same thing. If you go read a good C++ from the ground up kind of book, you'll find it first starting with a struct and then changing the 'struct' word to 'class' and starting to instantiate it using the straight name.

Edit: And... make sure you read the comment from @Bathsheba below and check proper naming conventions within C. As he points out, it should be _pTPObjectHandles with a lower-case p. For my own style, I avoid using uppercase typedefs too simply because I like my upper-case types to be true classes in C++ and want to know when they're just typedefs. But, again, that's a style choice.

Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69
1

It's partly so you can forward reference the structure inside itself but also use a meaningful name in the rest of the code, this:

struct _mylist
{
    struct _mylist *next;
    /* etc ... */
};

typedef struct _mylist MyList;

Note that switching the order round makes things a little more readable, but you still need the two declarations, thus:

typedef struct _mylist MyList;

struct _mylist
{
    MyList *next;
    /* etc ... */
};

What you can't do is this:

typedef struct { MyList *next; } MyList;

so you have to have the 2 declarations.

I tend to use something similar to the first form, like this:

typedef struct _mylist
{
    struct _mylist *next;
    /* etc ... */
} MyList;

as it makes it fairly clear the two types are meant to be the same.

Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
0

after that line of code, you can create struct by just using PTPObjectHandles. creating that struct

without typedef struct _PTPObjectHandles aStruct;
with typedef: PTPObjectHandles aStruct;

Chantara
  • 13
  • 2
0

This pattern is used to say "_PTPObjectHandles is an internal (technical) name, don't use it. Use PTPObjectHandles instead."

Generally, in C, a leading underscore means "this is internal, go away". It's a cheap solution for a language that doesn't have proper name spaces (note: I'm talking about plain C here, not C++).

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • But why even define the internal name if it is never ever used? Also, I've heard that leading underscores should never be used and trailing underscores are the way to go for internal stuff because names with leading underscore are reserved. – iFreilicht Apr 01 '14 at 14:38
  • Simple: You can't omit it, so how to you plan to compile the code with out it? – Aaron Digulla Apr 01 '14 at 16:36