One big use of unions in programs is to create variant types. A variant variable can change its type dynamically while the program is running. A variant object can be an integer at one point in the program, switch to a string at a different part of the program, and then change to a real value at a later time. Many very-high-level language (VHLL) systems use a dynamic type system (that is, variant objects) to reduce the overall complexity of the program; indeed, proponents of many VHLLs insist that the use of a dynamic typing system is one of the reasons you can write complex programs with so few lines of code using those languages. Of course, if you can create variant objects in a VHLL, you can certainly do it in assembly language. In this section we'll look at how we can use the union
structure to create variant types.
At any one given instant during program execution, a variant object has a specific type, but under program control the variable can switch to a different type. Therefore, when the program processes a variant object, it must use an if
statement or switch
statement (or something similar) to execute different instructions based on the object's current type. Very-high-level languages do this transparently. In assembly language you will have to provide the code to test the type yourself. To achieve this, the variant type needs some additional information beyond the object's value. Specifically, the variant object needs a field that specifies the current type of the object. This field (often known as the tag
field) is an enumerated type or integer that specifies the object's type at any given instant. The following code demonstrates how to create a variant type:
type VariantType: record tag:uns32; // 0-uns32, 1-int32, 2-real64 union u:uns32; i:int32; r:real64; endunion; endrecord; static v:VariantType;
The program would test the v.tag
field to determine the current type of the v
object. Based on this test, the program would manipulate the v.i
, v.u
, or v.r
field.
Of course, when operating on variant objects, the program's code must constantly be testing the tag
field and executing a separate sequence of instructions for uns32
, int32
, or real64
values. If you use the variant fields often, it makes a lot of sense to write procedures to handle these operations for you (e.g., vadd
, vsub
, vmul
, and vdiv
).