I just saw the following two lines in /usr/include/usb.h and my head is
spinning:
struct usb_dev_handle;
typedef struct usb_dev_handle usb_dev_handle;
What is that supposed to mean ?
I assume the first line is a forward declaration.
I can't find a definition for it, so does that mean it's like a void ?
Apparently gdb is confused as well as I can't seem to display anything based
on this struct.
The line is declaring that a struct with a tag of usb_dev_handle
exists (which code would refer to as "struct usb_dev_handle"). The
second line allows a shorter form to be used for it's name (just
"usb_dev_handle"). Because no information about what's in the struct
has been given, it's a so-called "incomplete type"; you can pass
pointers to it around, but not create an object of that type (at least
not safely, if you don't know how big it is). Normally, there'll be
some library function around that does know the details of the type
and which can create objects of that type; however, you have no way to
access the details yourself without that info, and neither does your
debugger (if you loaded debug information into it from the library,
assuming you have that information, it'll be able to display
information as it would with a complete type).
void is linked to this, in that it's an incomplete type that cannot be
completed, and so you can perform the same operations with it, but no
more:
struct usb_dev_handle;
typedef struct usb_dev_handle usb_dev_handle;
void* a; /* fine */
usb_dev_handle* b; /* fine */
void c; /* error */
usb_dev_handle d; /* error */
void func(void) /* void has a special meaning here that has nothing
to do with incomplete types */
{
usb_dev_handle e; /* error */
usb_dev_handle *f; /* fine */
void g; /* error */
void *h; /* fine */
h=malloc(10); /* legal, but probably a bad idea to use a magic
number here */
h=malloc(10*sizeof(void)); /* would be safer if it made sense, but
it doesn't */
f=malloc(10); /* legal but very stupid, as you have no idea how big
a
usb_dev_handle is */
f=malloc(10*sizeof(*f)); /* error, because the compiler has no idea
how big a
usb_dev_handle is either */
}