op ol
op ol

Reputation: 767

Confusion about a notation of a union type in a structure

This msdn page shows how INPUT is defined.

typedef struct tagINPUT {
  DWORD type;
  union {
    MOUSEINPUT    mi;
    KEYBDINPUT    ki;
    HARDWAREINPUT hi;
  } DUMMYUNIONNAME;
} INPUT, *PINPUT, *LPINPUT;

Case 1

#include <windows.h>

int main()
{
  INPUT input = { 0 };
  input.DUMMYUNIONNAME.ki.wScan = 0x12;
}

Case 2

#include <windows.h>

int main()
{
  INPUT input = { 0 };
  input.ki.wScan = 0x12;
}

But case 1 isn't compiled with g++ compiler but case 2 is compiled with no diagnostic messages. When considering the definition of INPUT, the results seem reversed. Am I missing a point?

Upvotes: 2

Views: 398

Answers (1)

nickelpro
nickelpro

Reputation: 2917

You're missing part of the equation.

For compilers that support anonymous unions, DUMMYUNIONNAME is an empty macro:

#define DUMMYUNIONNAME

typedef struct tagINPUT {
  DWORD type;
  union {
    MOUSEINPUT    mi;
    KEYBDINPUT    ki;
    HARDWAREINPUT hi;
  } DUMMYUNIONNAME;
} INPUT, *PINPUT, *LPINPUT;

An anonymous union merges into its parent's scope. That is why input.ki.wScan = 0x12; works.

For compilers that don't support anonymous unions, DUMMYUNIONNAME is defined to u instead:

#define DUMMYUNIONNAME u

typedef struct tagINPUT {
  DWORD type;
  union {
    MOUSEINPUT    mi;
    KEYBDINPUT    ki;
    HARDWAREINPUT hi;
  } DUMMYUNIONNAME;
} INPUT, *PINPUT, *LPINPUT;

In which case, you would have to use input.u.ki.wScan = 0x12; instead.

Upvotes: 4

Related Questions