UNION/END UNION block

Remarks

A union is a type - very similar to a User-Defined Type - except that its elements overlap in memory. While this may seem strange at first, it has enormous potential.

For example, say you are designing an accounting program. You want to make it general purpose so it has widespread appeal. But everyone does their accounting differently; for example, some people use account numbers that are plain integral values, while others may use alphanumeric account names. Using a Union makes this easy. Another common use of a Union is variable type conversion. The is best described by way of an example:

UNION VarConvert

iLong AS LONG

iDword AS DWORD

sStr AS STRING * 4

END UNION

DIM x AS VarConvert, y AS DWORD, z AS STRING

x.iLong = 123456&

y = x.iDword

z = x.sStr

Like a User-Defined Type, a Union may also contain arrays, and these follow the same rules as User-Defined Type member arrays (see Type Members for syntax rules and additional examples). The following example demonstrates the use of a Union member array:

UNION Arrs

a1(1 TO 1024) AS BYTE

st AS ASCIIZ * 10

END UNION

FUNCTION PBMAIN

DIM a AS Arrs

a.a1(1) = 72

a.a1(2) = 101

a.a1(3) = 108

a.a1(4) = 108

a.a1(5) = 111

a.a1(6) = 33

' At this point, a.st contains "Hello!"

END FUNCTION

Bit Variables

UNION structures may contain bit variables, which are named BIT (unsigned values) or SBIT (signed values). Each bit variable may occupy from 1 to 31 bits, and they may be packed one after another up to a total of 32 bits per bit field. The size of a bit variable is defined as follows:

var AS BIT * nlit [IN BYTE|WORD|DWORD]

where the term "* nlit" defines the number of bits (1 to 31), and the optional term "IN BYTE|WORD|DWORD", if present, defines the start of a new bit field of 1, 2, or 4 bytes. For example:

UNION ABCDE

Odd1 AS BIT * 1 IN DWORD

Value1 AS LONG

END UNION

The example UNION structure above is 4 bytes in size, containing a 1-byte bit field and a 4-byte LONG.

UNION abcde

Part1 AS BIT * 8 IN DWORD

Part2 AS BIT * 16

END UNION

The example union above is 4 bytes in size, containing an 8-bit field and an overlapping 16-bit field.

Structures within structures

Structures (TYPE/UNION) may be embedded within another structure, for simplification in referencing deeply nested items, by simply stating the structure name alone at the appropriate position. The internal alignment of the member structure is precisely maintained regardless of other alignment specifications, to foster inheritance issues. For example:

TYPE ABCD3 A AS LONG ABCD2 C AS LONG END TYPE | TYPE ABCD2 D AS DWORD E AS DOUBLE ABCD1 END TYPE | UNION ABCD1 F AS DWORD G AS LONG H AS SINGLE END UNION

In this case, you could access the lone Single-precision float member of this structure very simply. Assuming DIM X AS ABCD3, you could reference the Single-precision Union member with the variable name X.H, instead of the extended syntax X.ABCD2.ABCD1.H

Restrictions

A Union can contain elements of dissimilar sizes. The size of a Union structure is always determined by the longest member element. This is usually an important consideration when using a Union within another Union or UDT structure, in order to determine the size of the final structure.

For related information, please refer to the TYPE/END TYPE, User-Defined Types and Unions sections.

Field strings cannot be used in UDT or UNION structures. Attempting to do so results in a compile-time Error 485 ("Dynamic/Field strings not allowed").

See also | DIM, LEN, LET (with Types), SIZEOF, TYPE/END TYPE, User-Defined Types, Unions

Example

UNION AccountUnion

AccountNumber AS LONG

AccountName AS STRING * 16

END UNION

TYPE JournalEntryType

Account AS AccountUnion

Amount AS CUR

END TYPE

DIM JournalEntry AS JournalEntryType

JournalEntry.Account.AccountName = "Smith"

JournalEntry.Amount = 123.01@

' process journal entry here

JournalEntry.Account.AccountNumber = 1001

JournalEntry.Amount = -1.99@