modula-2 home

  Win32 API  


Type declarations

Record types

Record types are structures that contain named components.  The named components can be of different types.  The components of a record are called fields.

Parts of a record can have multiple definitions to allow the information stored in a record to vary according to different needs.  These parts are called variant sections.

The identifier following CASE in variant sections is called the tag field of the variant section.  Its value indicates which variant is present in the record.

To specify record types, use:


FieldListSequence is:

FieldList {;FieldList}

FieldList is either of the following:

identifier {,identifier}: TypeSpecification


CASE [identifier] : TypeName OF
   variant {|variant}
[ELSE FieldListSequence]

Variant is:

[ CaseRange {,CaseRange}: FieldListSequence ]

CaseRange is:

expression [..expression] {, expression [..expression]}


   X, Y : REAL;

This record has two fields, X and Y, both of type REAL.  This record might be used to represent a point in a plane.

   NEXT : NodePointer;
   CASE NT : NodeType OF
           op  : OperatorType;
           left, right : NodePointer;
           value : REAL;

This record has one field, NEXT, followed by a variant section.  The variant section has two variants, one for the NodeType Operator and one for Operand.

A variant in a RECORD must handle all possible values of the tag field type. Thus if the CASE selector arms do not handle all possible values you must have an ELSE section in the CASE. The ELSE section can be empty. In this way you are informing the compiler you understand that all values are not handled and this is the necessary behavior.

Field selection

You can select a field of a record type variable as follows:


Where variable is a record variable and field is the name of the field.

If the field is a part of a variant section with a tag field specified, it is an error to refer to any field in a variant other than the one specified by the tag field.

If you refer to a field in an incorrect variant, and the module was compiled with variant checking on, the program generates a runtime error.

Copying of variant records

The compiler allocates variables of variant record types the maximum amount of memory needed by any variant.  These variables are, therefore, capable of holding any variant, and copying one record to another will work correctly.

If you use the NEW standard procedure to allocate a variant record and specify the values of the tag fields, the compiler allocates only enough memory for the specific variants you selected.

You cannot do assignments of the entire record to records allocated in that way, because the amount of space allocated might not be large enough to hold the record you are assigning.

If you intend to do an assignment of the whole record, use NEW without specifying any tags.   In this case, the compiler allocates space for the largest variant.


              CASE Tag : INTEGER OF
                 1: R : REAL; |
                 2: L : LONGREAL;
      A : VARREC;
      B^ := A;  (* Correct *)
      NEW(B, 1);
      B^ := A;  (* Incorrect *)


  • Wirth N: Programming in Modula-2, 3rd ed. Springer Verlag, Berlin, 1985.
  • Stony Brook Modula-2 documentation. Used with permission. Note: Stony-Brook M2 offers an extended syntax with features not described here. Stony Brook M2 users are encouraged to visit the Stony Brook website and to consult the Stony Brook help system.