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?
Structures (also called structs) are a way to group several related variables into one place. Each variable in the structure is known as a member of the structure. Unlike an array, a structure can contain many different data types (int, float, char, etc.).
Syntax to Define a Structure in CstructName: This is the name of the structure which is specified after the keyword struct. data_Type: The data type indicates the type of the data members of the structure. A structure can have data members of different data types.
struct structureName { dataType member1; dataType member2; ... }; For example, struct Person { char name[50]; int citNo; float salary; }; Here, a derived type struct Person is defined.
Structure members can be initialized using curly braces '{}'.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With