* Re: Tagged type feature, or GNAT bug?
1994-09-27 16:36 Tagged type feature, or GNAT bug? Michael Feldman
@ 1994-09-27 23:22 ` Bob Duff
1994-09-28 11:14 ` Robert Dewar
1 sibling, 0 replies; 3+ messages in thread
From: Bob Duff @ 1994-09-27 23:22 UTC (permalink / raw)
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.)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Tagged type feature, or GNAT bug?
1994-09-27 16:36 Tagged type feature, or GNAT bug? Michael Feldman
1994-09-27 23:22 ` Bob Duff
@ 1994-09-28 11:14 ` Robert Dewar
1 sibling, 0 replies; 3+ messages in thread
From: Robert Dewar @ 1994-09-28 11:14 UTC (permalink / raw)
Obviously you can't have an array of type'Class, because the whole point is
that you don't know till link time what the maximum size of such an object
would be. So if you think about it Mike, you have no implementation model
for how that would work except to introduce pointers, and the solution is
simple enough: introduce the pointers in the code. Always work with pointers
to T'Class, not T'Class objects themselves.
Actually that's good advice in the variant record case too. In general the
business of allocating the maximum possible space doesn't work so well even
for variant records where you know all the possibilities statically. Some
Ada 83 compilers (RR?) introduce hidden pointers in this case, and others
(ALsys) allocate the maximum space, but place an arbitrary limit on the
maximum size permitted.
It's helpful always to think about what your implementation model is when
you run into something like this. If you can't think of a simple model, then
very likely there is a problem!
Robert
^ permalink raw reply [flat|nested] 3+ messages in thread