Contents Index Search Previous Next
3.9.2 Dispatching Operations of Tagged Types
1
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
2
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.
3
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:
4
- 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;
5
- 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;
6
- 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.
7/1
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 an object that is designated by an expression
whose expected type is an anonymous access-to-specific tagged type, the
object is dynamically tagged if the expression, ignoring enclosing parentheses,
is of the form X'Access, where X is of a class-wide type, or is of the
form new T'(...), where T denotes a class-wide subtype. Otherwise,
the object is statically or dynamically tagged according to whether the
designated type of the type of the expression is specific or class-wide,
respectively.
Legality Rules
8
A call on a dispatching operation shall not have
both dynamically tagged and statically tagged controlling operands.
9/1
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
object designated by the expression shall not be dynamically tagged unless
it is a controlling operand in a call on a dispatching operation.
10/1
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
6.1), 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.
The
convention of an inherited or overriding dispatching operation is the
convention of the corresponding primitive operation of the parent type.
An explicitly declared dispatching operation shall not be of convention
Intrinsic.
11
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.
12
A given subprogram shall not be a dispatching
operation of two or more distinct tagged types.
13
The explicit declaration of a primitive subprogram
of a tagged type shall occur before the type is frozen (see
13.14).
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
14
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:
15
- If one or more
controlling operands are statically tagged, then the controlling tag
value is statically determined to be the tag of T.
16
- 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.
17
- If all
of the controlling operands are tag-indeterminate, then:
18
- 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;
19
- Otherwise,
the controlling tag value is statically determined to be the tag of type
T.
20
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.
21
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.
22
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 5.2.
23
72 A dispatching call can
dispatch to a body whose declaration is not visible at the place of the
call.
24
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.
Contents Index Search Previous Next Legal