[comp.lang.ada] variant records

stuart@inmet.UUCP (11/05/86)

Objects created with an allocator are always constrained.  If 
explicit constraints are not supplied, the object is constrained 
by the default discriminant values (LRM 4.8(5)).  The easiest 
solution would be to declare the type "node" without discriminants:

    type node;
    type node_ptr is access node;
    type node is
        record
            next : node_ptr;
            xrec : rec;      -- will not be constrained
        end record;

If you want save space by allocating exact sized constrained objects,
"node" can be declared with discriminates.  However, calls on "new"
must include a constraint, and the free list would have to be an array 
of free lists, one for each possible discriminant value.

stt@ada-uts (11/06/86)

You have fallen into a couple of Ada traps.
First, all objects created by an allocator are constrained,
even if the type has defaults (see LRM 4.8:5 "If the type
of the created object is an array type or a type with
discriminants, the the created object is always constrained.")
Hence, by saying simply "new node" you have created an object
with the default discriminant, and constrained to stay that way.

Secondly, by having a record component whose discriminant depends
on the discriminant of the enclosing record, the component is
constrained by the enclosing discriminant, and the enclosing
discriminant cannot be changed by assigning to just the component.

To solve your problem, you should either remove the discriminant
from the outer record type "node" and declare the xrec component
without a discriminant (hence unconstrained), or maintain separate
node free lists for each distinct discriminant value, and allocate
using "new node(discrim)" where discrim is the discriminant of
the component rec being pushed (this will require that you pass
discrim as a parameter to your "new_node" function).