Go to the first, previous, next, last section, table of contents.
-
The primitive subprograms of a tagged type are called dispatching
operations. A dispatching operation can be called using a statically
determined controlling tag, in which case the body to be executed is
determined at compile time. Alternatively, the controlling tag can be
dynamically determined, in which case the call dispatches to a body that
is determined at run time; such a call is termed a dispatching call. As
explained below, the properties of the operands and the context of a
particular call on a dispatching operation determine how the controlling
tag is determined, and hence whether or not the call is a dispatching
call. Run-time polymorphism is achieved when a dispatching operation is
called by a dispatching call.
Static Semantics
-
A call on a dispatching operation is a call whose name or prefix denotes
the declaration of a primitive subprogram of a tagged type, that is, a
dispatching operation. A controlling operand in a call on a dispatching
operation of a tagged type T is one whose corresponding formal parameter
is of type T or is of an anonymous access type with designated type T;
the corresponding formal parameter is called a controlling formal
parameter. If the controlling formal parameter is an access parameter,
the controlling operand is the object designated by the actual
parameter, rather than the actual parameter itself. If the call is to a
(primitive) function with result type T, then the call has a controlling
result -- the context of the call can control the dispatching.
-
A name or expression of a tagged type is either statically tagged,
dynamically tagged, or tag indeterminate, according to whether, when
used as a controlling operand, the tag that controls dispatching is
determined statically by the operand's (specific) type, dynamically by
its tag at run time, or from context. A qualified_expression or
parenthesized expression is statically, dynamically, or indeterminately
tagged according to its operand. For other kinds of names and
expressions, this is determined as follows:
-
The name or expression is statically tagged if it is of a specific
tagged type and, if it is a call with a controlling result, it has at
least one statically tagged controlling operand;
-
The name or expression is dynamically tagged if it is of a class-wide
type, or it is a call with a controlling result and at least one
dynamically tagged controlling operand;
-
The name or expression is tag indeterminate if it is a call with a
controlling result, all of whose controlling operands (if any) are tag
indeterminate.
-
A type_conversion is statically or dynamically tagged according to
whether the type determined by the subtype_mark is specific or
class-wide, respectively. For a controlling operand that is designated
by an actual parameter, the controlling operand is statically or
dynamically tagged according to whether the designated type of the
actual parameter is specific or class-wide, respectively.
Legality Rules
-
A call on a dispatching operation shall not have both dynamically tagged
and statically tagged controlling operands.
-
If the expected type for an expression or name is some specific tagged
type, then the expression or name shall not be dynamically tagged unless
it is a controlling operand in a call on a dispatching operation.
Similarly, if the expected type for an expression is an anonymous
access-to-specific tagged type, then the expression shall not be of an
access-to-class-wide type unless it designates a controlling operand in
a call on a dispatching operation.
-
In the declaration of a dispatching operation of a tagged type,
everywhere a subtype of the tagged type appears as a subtype of the
profile, See section 6.1 Subprogram Declarations, it shall statically match the first subtype of the
tagged type. If the dispatching operation overrides an inherited
subprogram, it shall be subtype conformant with the inherited
subprogram. A dispatching operation shall not be of convention
Intrinsic. If a dispatching operation overrides the predefined equals
operator, then it shall be of convention Ada (either explicitly or by
default -- See section 6.3.1 Conformance Rules.).
-
The default_expression for a controlling formal parameter of a
dispatching operation shall be tag indeterminate. A controlling formal
parameter that is an access parameter shall not have a
default_expression.
-
A given subprogram shall not be a dispatching operation of two or more
distinct tagged types.
-
The explicit declaration of a primitive subprogram of a tagged type
shall occur before the type is frozen, See section 13.14 Freezing Rules. For example, new
dispatching operations cannot be added after objects or values of the
type exist, nor after deriving a record extension from it, nor after a
body.
Dynamic Semantics
-
For the execution of a call on a dispatching operation of a type T, the
controlling tag value determines which subprogram body is executed. The
controlling tag value is defined as follows:
-
If one or more controlling operands are statically tagged, then the
controlling tag value is statically determined to be the tag of T.
-
If one or more controlling operands are dynamically tagged, then the
controlling tag value is not statically determined, but is rather
determined by the tags of the controlling operands. If there is more
than one dynamically tagged controlling operand, a check is made that
they all have the same tag. If this check fails, Constraint_Error is
raised unless the call is a function_call whose name denotes the
declaration of an equality operator (predefined or user defined) that
returns Boolean, in which case the result of the call is defined to
indicate inequality, and no subprogram_body is executed. This check is
performed prior to evaluating any tag-indeterminate controlling
operands.
-
If all of the controlling operands are tag-indeterminate, then:
-
If the call has a controlling result and is itself a (possibly
parenthesized or qualified) controlling operand of an enclosing call on
a dispatching operation of type T, then its controlling tag value is
determined by the controlling tag value of this enclosing call;
-
Otherwise, the controlling tag value is statically determined to be the
tag of type T.
-
For the execution of a call on a dispatching operation, the body
executed is the one for the corresponding primitive subprogram of the
specific type identified by the controlling tag value. The body for an
explicitly declared dispatching operation is the corresponding explicit
body for the subprogram. The body for an implicitly declared dispatching
operation that is overridden is the body for the overriding subprogram,
even if the overriding occurs in a private part. The body for an
inherited dispatching operation that is not overridden is the body of
the corresponding subprogram of the parent or ancestor type.
NOTES
-
(70) The body to be executed for a call on a dispatching operation is
determined by the tag; it does not matter whether that tag is determined
statically or dynamically, and it does not matter whether the
subprogram's declaration is visible at the place of the call.
-
(71) This subclause covers calls on primitive subprograms of a tagged
type. Rules for tagged type membership tests are described in 4.5.2.
Controlling tag determination for an assignment_statement is described
in See section 5.2 Assignment Statements.
-
(72) A dispatching call can dispatch to a body whose declaration is not
visible at the place of the call.
-
(73) A call through an access-to-subprogram value is never a dispatching
call, even if the access value designates a dispatching operation.
Similarly a call whose prefix denotes a subprogram_renaming_declaration
cannot be a dispatching call unless the renaming itself is the
declaration of a primitive subprogram.
Go to the first, previous, next, last section, table of contents.