by Richard Russell, September 2016

A union is a value or data structure that may have two or more different representations or formats. Liberty BASIC doesn't have unions, but it is simple to simulate them in LBB using structures. The trick is to create two (or more) structures, which should be the same size, and then to arrange for them to share the same memory address.

Here is a simple example of creating a union between two 32-bit integers and a 64-bit floating-point double:

    struct union1, low as ulong, high as ulong
    struct union2, float as double
    union2.struct = union1.struct
    union1.low.struct = hexdec("1A9FBE77")
    union1.high.struct = hexdec("405EDD2F")
    print union2.float.struct
Here the structure union1 contains the two 32-bit integers and the structure union2 contains the floating-point double. The third line sets union2 to point to the same memory block as union1. Hence you can write and read the data using either of the two formats. In the example above the data is written as two integers and read as a double, but the converse is just as straightforward.

Note that, unlike languages which have true unions, this technique will not save memory. The memory originally allocated to the structure union1 is leaked, but that is very unlikely to matter.

You can use the same technique to convert between a numeric value and a string containing the same data in binary format. For example here is an example of creating a union between an 8-character-long string and a 64-bit double:

    struct union1, string as char[9]
    struct union2, number as double, pad as char[1]
    union2.struct = union1.struct
    union1.string.struct = chr$(119)+chr$(190)+chr$(159)+chr$(26)+ _
    print union2.number.struct
Note that in this case there is a slight complication in that the string is declared as char[9] rather than as char[8] as you might expect; that's because you have to make room for the additional NUL character chr$(0) which terminates the string. It also results in the structures being a different length, so to avoid memory corruption and a probable crash union2 is padded to the same length as union1 (this isn't strictly essential if the shorter structure is equated to the longer structure rather than the other way around).