- In addition to the various language-defined classes of types, types can
be grouped into derivation classes.
- A derived type is derived from its parent type directly; it is derived
indirectly from any type from which its parent type is derived. The
derivation class of types for a type T (also called the class rooted at T) is
the set consisting of T (the root type of the class) and all types derived
from T (directly or indirectly) plus any associated universal or class-wide
types (defined below).
- Every type is either a specific type, a class-wide type, or a universal
type. A specific type is one defined by a type_declaration, a formal_type_declaration, or a full type definition embedded in a declaration for an
object. Class-wide and universal types are implicitly defined, to act as
representatives for an entire class of types, as follows:
- Class-wide types
Class-wide types are defined for (and belong to) each derivation class rooted
at a tagged type (see 3.9). Given a subtype S of
a tagged type T, S'Class is the subtype_mark for a corresponding subtype
of the tagged class-wide type T'Class. Such types are called ``class-wide''
because when a formal parameter is defined to be of a class-wide type T'Class,
an actual parameter of any type in the derivation class rooted at T is acceptable
The set of values for a class-wide type T'Class is the discriminated union
of the set of values of each specific type in the derivation class rooted
at T (the tag acts as the implicit discriminant -- see
3.9). Class-wide types have no primitive subprograms of their own. However,
as explained in 3.9.2, operands of a class-wide
type T'Class can be used as part of a dispatching call on a primitive subprogram
of the type T. The only components (including discriminants) of T'Class
that are visible are those of T. If S is a first subtype, then S'Class is
a first subtype.
- Universal types
Universal types are defined for (and belong to) the integer, real, and fixed
point classes, and are referred to in this standard as respectively, universal_integer,
universal_real, and universal_fixed. These are analogous to class-wide types
for these language-defined numeric classes. As with class-wide types, if
a formal parameter is of a universal type, then an actual parameter of any
type in the corresponding class is acceptable. In addition, a value of a
universal type (including an integer or real numeric_literal) is ``universal''
in that it is acceptable where some particular type in the class is expected
The set of values of a universal type is the
undiscriminated union of the set of values possible for any
definable type in the associated class. Like class-wide
types, universal types have no primitive subprograms of their
own. However, their ``universality'' allows them to be used
as operands with the primitive subprograms of any type in the
- The integer and real numeric classes each have a specific root type in
addition to their universal type, named respectively root_integer and root_real.
- A class-wide or universal type is said to cover all of the types in its
class. A specific type covers only itself.
- A specific type T2 is defined to be a descendant of a type T1 if T2 is
the same as T1, or if T2 is derived (directly or indirectly) from T1. A
class-wide type T2'Class is defined to be a descendant of type T1 if T2 is a
descendant of T1. Similarly, the universal types are defined to be
descendants of the root types of their classes. If a type T2 is a descendant
of a type T1, then T1 is called an ancestor of T2. The ultimate ancestor of
a type is the ancestor of the type that is not a descendant of any other
- An inherited component (including an inherited discriminant) of a
derived type is inherited from a given ancestor of the type if the
corresponding component was inherited by each derived type in the chain of
derivations going back to the given ancestor.
(18) Because operands of a universal type are acceptable to the predefined
operators of any type in their class, ambiguity can result. For universal_integer
and universal_real, this potential ambiguity is resolved by giving a preference
(see 8.6) to the predefined operators of the corresponding
root types (root_integer and root_real, respectively). Hence, in an apparently
ambiguous expression like
1 + 4 < 7
where each of the literals is of type universal_integer, the
predefined operators of root_integer will be preferred over those of
other specific integer types, thereby resolving the ambiguity.
-- Email comments, additions, corrections, gripes, kudos, etc. to:
Magnus Kempe -- Magnus.Kempe@di.epfl.ch
Page last generated: 95-03-12