8.3.1 Overriding Indicators
1/2
{
AI95-00218-03}
An overriding_indicator
is used to declare that an operation is intended to override (or not
override) an inherited operation.
Syntax
2/2
Legality Rules
3/2
{
AI95-00218-03}
{
AI95-00348-01}
{
AI95-00397-01}
If an abstract_subprogram_declaration,
null_procedure_declaration, subprogram_body,
subprogram_body_stub, subprogram_renaming_declaration,
generic_instantiation of a subprogram, or
subprogram_declaration other than a protected
subprogram has an overriding_indicator, then:
4/2
- the operation
shall be a primitive operation for some type;
5/2
- if the overriding_indicator
is overriding, then the operation shall override a homograph at
the place of the declaration or body;
6/2
- if the overriding_indicator
is not overriding, then the operation shall not override any homograph
(at any place).
7/2
{generic
contract issue [partial]} In addition
to the places where Legality Rules normally apply, these rules also apply
in the private part of an instance of a generic unit.
7.a/2
Discussion: The
overriding and not overriding rules differ slightly. For
overriding, we want the indicator to reflect the overriding state
at the place of the declaration; otherwise the indicator would be “lying”.
Whether a homograph is implicitly declared after the declaration (see
7.3.1 to see how this can happen) has no impact on this check. However,
not overriding is different; “lying” would happen
if a homograph declared later actually is overriding. So, we require
this check to take into account later overridings. That can be implemented
either by looking ahead, or by rechecking when additional operations
are declared.
7.b/2
The “no lying”
rules are needed to prevent a subprogram_declaration
and subprogram_body from having contradictory
overriding_indicators.
8/2
8 {
AI95-00397-01}
Rules for overriding_indicators
of task and protected entries and of protected subprograms are found
in 9.5.2 and 9.4,
respectively.
Examples
9/2
{
AI95-00433-01}
The use of overriding_indicators
allows the detection of errors at compile-time that otherwise might not
be detected at all. For instance, we might declare a security queue derived
from the Queue interface of 3.9.4 as:
10/2
type Security_Queue is new Queue with record ...;
11/2
overriding
procedure Append(Q : in out Security_Queue; Person : in Person_Name);
12/2
overriding
procedure Remove_First(Q : in out Security_Queue; Person : in Person_Name);
13/2
overriding
function Cur_Count(Q : in Security_Queue) return Natural;
14/2
overriding
function Max_Count(Q : in Security_Queue) return Natural;
15/2
not overriding
procedure Arrest(Q : in out Security_Queue; Person : in Person_Name);
16/2
The first four subprogram
declarations guarantee that these subprograms will override the four
subprograms inherited from the Queue interface. A misspelling in one
of these subprograms will be detected by the implementation. Conversely,
the declaration of Arrest guarantees that this is a new operation.
16.a/2
Discussion: In
this case, the subprograms are abstract, so misspellings will get detected
anyway. But for other subprograms (especially when deriving from concrete
types), the error might never be detected, and a body other than the
one the programmer intended might be executed without warning. Thus our
new motto: “Overriding indicators — don't derive a type without
them!”
Extensions to Ada 95
16.b/2
{
AI95-00218-03}
{extensions to Ada 95} Overriding_indicators
are new. These let the programmer state her overriding intentions to
the compiler; if the compiler disagrees, an error will be produced rather
than a hard to find bug.