Ccorock
Ccorock

Reputation: 892

C structure syntax

C header sample.

typedef LPVOID UKWD_USB_DEVICE;

typedef struct _UKWD_USB_DEVICE_INFO {
    DWORD dwCount;
    unsigned char Bus;
    unsigned char Address;
    unsigned long SessionId;
    USB_DEVICE_DESCRIPTOR Descriptor;
} UKWD_USB_DEVICE_INFO, *PUKWD_USB_DEVICE_INFO, * LPUKWD_USB_DEVICE_INFO;

My Understanding

struct defines a structure (the part between {}). The structure's type is _UKWD_USB_DEVICE_INFO. After the closing } UKWD_USB_DEVICE_INFO is an alias to this structure.

Question

What is the purpose of the declarations after that. * PUKD_USB_DEVICE_INFO and *LPUKWD_USB_DEVICE_INFO. Do these pointer aliases mean something different if one is touching the variable and the other has a space between the * and lettering?

Upvotes: 5

Views: 262

Answers (4)

user4520
user4520

Reputation: 3459

Yes, it's a pointer alias, you can then use PUKWD_USB_DEVICE_INFO as UKWD_USB_DEVICE_INFO*. Most Windows structs do this:

enter image description here

That L in the third alias stands for long (pointer), and unless I'm much mistaken, it has no meaning in 32/64 bit code - it's likely a leftover from 16 bit stuff, as is the case with that WNDCLASS definition.

Upvotes: 1

chqrlie
chqrlie

Reputation: 144550

This style of definition is common on the Windows platform. In the days of 16 bit segmented architectures, each structure definition typedef had also 2 pointer typedefs for near and far (aka long pointers):

typedef LPVOID UKWD_USB_DEVICE;

typedef struct _UKWD_USB_DEVICE_INFO {
    DWORD dwCount;
    unsigned char Bus;
    unsigned char Address;
    unsigned long SessionId;
    USB_DEVICE_DESCRIPTOR Descriptor;
} UKWD_USB_DEVICE_INFO, NEAR * PUKWD_USB_DEVICE_INFO, FAR * LPUKWD_USB_DEVICE_INFO;

NEAR pointers were 16 bit wide and FAR pointers were 32 bit wide. Most Windows APIs took FAR pointers, and their prototypes used the pointer typedefs. Incidentally, LPVOID was defined this way:

typedef void FAR *LPVOID;

32 bit Windows came out in 1995 and made this obsolete. NEAR and FAR keywords were kept for a while, defined as empty, for compatibility reasons.

Compatibility with 16 bit Windows has long become useless, but the usage still lingers as the typedefs are still in use, but the FAR and NEAR keywords were removed.

The space between * and PUKWD_USB_DEVICE_INFO is ignored, but I agree with you it is rather confusing to put one there.

Upvotes: 1

Drew Dormann
Drew Dormann

Reputation: 63704

Are these pointer aliases?

Yes.

Does it mean anything if one is touching the variable and the other has a space between the * and lettering?

No. In C, spaces between tokens have no meaning to the compiler. They merely change the readability for people looking at the code.

I have seen very few code examples online use more than one name after the close of the curly brackets. Any insight on this?

Typically, and in this case in particular, it's done to allow symbol names that may represent different types, but also may not.

You're seeing that on your architecture, a P "pointer" and a LP "long pointer" happen to be the same type.

On a 16-bit architecture, you would be looking at a different header and those types would be different.

Upvotes: 1

antron
antron

Reputation: 3847

C typedef declarations are understood by analogy with variable declarations.

int a, *b;

declares the values a of type int and b of type int*.

typedef int A, *B;

declares the type A equivalent to int and the type B equivalent to int*. So, just think about what the variable type would be if this was a variable declaration.

So yes, PUKWD_USB_DEVICE_INFO becomes equivalent to struct _UKWD_USB_DEVICE_INFO*.

EDIT

Also, the space does not matter. C is a whitespace language. The extra aliases are not necessary, they are just there to fit with conventions of various projects and APIs that like to call pointer types by names that include P or other substrings. Sometimes these projects end up with multiple conventions over time, so there are multiple aliases. They can also be needed for compatibility reasons when APIs get updated, or between different platforms.

Upvotes: 5

Related Questions