comp.lang.ada
 help / color / mirror / Atom feed
From: bobduff@dsd.camb.inmet.com (Bob Duff)
Subject: Re: Tagged type feature, or GNAT bug?
Date: Tue, 27 Sep 1994 23:22:33 GMT
Date: 1994-09-27T23:22:33+00:00	[thread overview]
Message-ID: <CwtA9M.143@inmet.camb.inmet.com> (raw)
In-Reply-To: 369hme$e9j@felix.seas.gwu.edu

In article <369hme$e9j@felix.seas.gwu.edu>,
Michael Feldman <mfeldman@seas.gwu.edu> wrote:
>-- CASE 1: array of unconstrained variant records. OK in Ada 83.
>
>  TYPE List IS ARRAY (1..4) OF VariantRec; -- unconstrained variant rec
>  Stuff: List;
>
>-- CASE 2: Now an array intended to hold any of the four types
>-- (by direct analogy with Case 1)
>
>-- GNAT rejects this - says the array elements must be constrained

GNAT is correct here.  The rule is in RM9X-3.6(10), which says the
component subtype has to be a definite subtype.  Class-wide subtypes are
not definite (see 3.3(23) and 3.7(26)).

Class-wide subtypes are like discriminated subtypes *without* defaults.

>  TYPE TaggedList IS ARRAY (1..4) OF TaggedRec'Class;
>  TaggedStuff: TaggedList;
>
>-- CASE 3: Array of_pointers_ to tagged records
>-- This will compile OK, but seems a gratuitously required use
>-- of pointers - very un-Ada-like.
>
>  TYPE TaggedRecPtr IS ACCESS TaggedRec'Class; 
>  TYPE TaggedListPtr IS ARRAY (1..4) OF TaggedRecPtr;
>  TaggedStuffPtr: TaggedList;

That's right -- you have to use pointers (ahem, I mean access types).

Basically, "definite" means the compiler knows how much space to
allocate.  Clearly, the compiler can't know how much space to allocate
for a class-wide subtype, because you can add type extensions later,
and these can have arbitrary sizes.

Since the compiler doesn't know how much space to allocate, you have to
use a pointer.

Ada, being intended for real-time applications, doesn't like to have
implicit pointers, and the corresponding implicit heap allocation.
Instead, whenever the compiler doesn't know the size, the language
requires the programmer to use pointers, and do the necessary
allocations "by hand".

In other words, the reason you can't have an array of class-wide is the
same reason you can't have an array of unconstrained arrays:

    type T is array(1..10) of String; -- Illegal!

This example makes perfect sense from a logical point of view, but would
require implicit heap management by the compiler.  Therefore, you have
to use an access-to-String type in this example.  Same thing for
class-wide.

Thus, when converting an application that uses
discriminants-with-defaults to one that uses class-wide types, you have
to introduce pointers.  For discriminants-with-defaults, the compiler
can see the whole variant record, and can figure out the maximum size.
For class-wide subtypes, however, the maximum size is unbounded.

There are some compilers that introduce implicit heap allocation for
discriminants with defaults.  However, that is by no means universal
among compilers, and is arguably naughty behavior in a real-time
environment.  We certainly didn't want to *require* such behavior for
class-wide subtypes.

Most other OOP languages that I know of have the same restriction --
most (e.g. Smalltalk) use pointer semantics *everywhere*, and the ones
that don't (e.g. C++) require the "tag" to be nailed down (and not
change) by the time an object is created.  In either case, to change a
tag normally requires deallocating and reallocating the object -- using
pointers.
-- 
Bob Duff                                bobduff@inmet.com
Oak Tree Software, Inc.
Ada 9X Mapping/Revision Team (Intermetrics, Inc.)



  reply	other threads:[~1994-09-27 23:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-09-27 16:36 Tagged type feature, or GNAT bug? Michael Feldman
1994-09-27 23:22 ` Bob Duff [this message]
1994-09-28 11:14 ` Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox