structs: unions

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

structs: unions

11 Jan 2019, 23:21

- Here is a definition of a union.
Unions | Microsoft Docs
https://docs.microsoft.com/en-us/cpp/cp ... ew=vs-2017
A union is a user-defined type in which all members share the same memory location. This means that at any given time a union can contain no more than one object from its list of members. It also means that no matter how many members a union has, it always uses only enough memory to store the largest member.
- So a union is a bit like a drop-down list, you choose one of the possible items.
- One query is, sometimes the possible items are of different sizes, in such cases, should it be assumed that the size of the union is always the size of the largest member? (Whether the largest member is used or not.)

Code: Select all

;==================================================

typedef struct _OVERLAPPED {
  ULONG_PTR Internal;
  ULONG_PTR InternalHigh;
  union {
    struct {
      DWORD Offset;
      DWORD OffsetHigh;
    } DUMMYSTRUCTNAME;
    PVOID Pointer;
  } DUMMYUNIONNAME;
  HANDLE    hEvent;
} OVERLAPPED, *LPOVERLAPPED;

;size (x64): 8 + 8 + Max(4+4,8) + 8 = 32
;size (x32): 4 + 4 + Max(4+4,4) + 4 = 20

;==================================================

typedef struct _STRRET {
  UINT  uType;
  union {
    LPWSTR pOleStr;
    UINT   uOffset;
    CHAR   cStr[MAX_PATH];
  };
} STRRET, *LPSTRRET;

;size (x64): 4+(4) + Max(8,4+(4),260+(4)) = 272
;size (x32): 4 + Max(4,4,260) = 264

;==================================================
- The STRRET struct question is complicated because if you rewrite the struct as 3 separate structs (each with a different union member), for x64: the LPWSTR must start at offset 8 (8-byte pointers appear at an offset that is a multiple of 8 bytes), whereas the other 2 members could appear at offset 4.
- And, if an LPWSTR is present (8 bytes), the struct size must be a multiple of 8, whereas for the other 2 members, the struct size must be a multiple of 4 since the biggest member is a UINT (4 bytes).
- So in x64:
UINT uType; LPWSTR pOleStr; [size: 4(4)+8 = 16]
UINT uType; UINT uOffset; [size: 4+4 = 8]
UINT uType; CHAR cStr[MAX_PATH]; [size: 4+260 = 264]
UINT uType; CHAR cStr[MAX_PATH]; [size: 4+(4)+260+(4) = 272] [taking into account LPWSTR pOleStr]
Where 272 is the value returned by sizeof().
- So, in x64, we consider 'CHAR cStr[MAX_PATH]', 260 bytes which could start at offset 4, but also consider 'LPWSTR pOleStr', which must start at offset 8, and demands an overall struct size that is a multiple of 8. So, should we combine all of the criteria when considering the union? E.g. the size of union option 3 with the padding requirements of union option 1.

- I also started this thread in case anyone has anything else interesting to say about unions. Thanks.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: structs: unions

12 Jan 2019, 03:26

The size of a union is the size of its largest member and its alignment must be the alignment of its member with the highest alignment.
The STRRET struct question is complicated because if you rewrite the struct as 3 separate structs (each with a different union member)
don't, there's no such thing, the union is the member of the struct, and it should be placed in the struct just like any other member in a struct, that is, according to its size and alignment requirement, which are as described above.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: structs: unions

12 Jan 2019, 10:09

The size of a union is the size of its largest member and its alignment must be the alignment of its member with the highest alignment.
Thanks a lot Helgef, this is a great description of the situation, and matches what I suspected. Do you have a source re. the alignment part? Thanks.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Chunjee, Theda and 103 guests