By John Barnes
A major design goal of Ada 95 was to minimize the need to modify existing Ada 83 software in order to make it compatible with Ada 95. However, the experience of revising other language standards has shown it is infeasible to achieve total compatibility and meet other important requirements. As a consequence there are a small number of incompatibilities of which the user should be aware.
Most incompatibilities can be dealt with in a simple way. The majority of programs will not be significantly affected - the most likely incompatibilities being automatically detected at compilation. Indeed, only three incompatibilities are considered likely to occur in normal programs. They are
- New reserved words - Ada 95 has six new reserved words.
- Type Character has 256 positions - In Ada 83, it had 128 positions.
- Indefinite generic parameters - Ada 95 has distinct syntax for a generic formal parameter allowing unconstrained actual parameters.
Two further incompatibilities might occur in normal programs but are less likely:
- Library package bodies - In Ada 95, it is illegal to provide a body for a library package not requiring one.
- Numeric_Error - In Ada 95, this has been changed to a renaming of Constraint_Error.
Most examples of the above five incompatibilities are detected at compilation time as discussed below. Other possible incompatibilities involving obscure programming styles are expected to be infrequent.
Ada 95 has six new reserved words: abstract, aliased, protected, requeue, tagged,
. An Ada 83 program that uses any of these as identifiers is an illegal Ada 95 program. For example, the following fragment of Ada 83 will fail to compile in Ada 95
Protected: Boolean := False;
procedure Requeue(My_Job: Job);
Avoidance and detection is clearly straightforward. However, extensive surveys of existing code have shown few programs to be affected.
In Ada 95, the type Character has 256 positions. In Ada 83, it had 128 positions. This change accommodates the ISO Latin-1 standard and thus the needs of many non-English speaking nations.
An Ada 83 program with a case statement or an array indexed by Character could be illegal in Ada 95; it could be inconsistent if it relied on the position or value of Character'Last. Consider
type Token is (Num, Alpha, Other);
array (Character) of Token := (1)
('0' .. '9' => Num,
'A' .. 'Z' | 'a' .. 'z' => Alpha,
others => Other);
case Char is (2)
when Character'Val(0) ..
Character'Val(63) => ...
when Character'Val(64) ..
Character'Val(127) => ...
I: Integer :=
Declaration (1) is legal in Ada 95 but might not achieve the desired effect. Statement (2) is illegal in Ada 95 and so detected at compilation. Statement (3) is inconsistent; the program will still execute but have a different effect in Ada 95.
As it is likely that allowing for 256 characters is outside the scope of the original requirement for the program concerned, avoidance is not really the issue - a review of the requirements is necessary.
The inconsistency illustrated by the third example can be avoided by not depending on
the position or value of Character'Last. Avoiding the other incompatibilities
avoids the real issue of how the extra 128 characters are to be handled. Unless uniform behaviour
is acceptable for these extra characters, use of an others choice, whilst
ensuring a legal (but bad style) Ada 95 program might cause unacceptable behaviour.
Detection of case (2) is straightforward. In other cases manual correction is necessary
to determine whether the required semantics of the program are those defined by Ada 95.
Finally, note that the ISO Working Group maintaining the Ada standard (the ARG),
has decreed that this change can be introduced into Ada 83 compilers, so this is
also an Ada 83 portability issue as more implementations support 256 characters.
Library Package Bodies
In Ada 95, library packages are allowed to have a body only if required by language rules. In Ada 83, a body need only be provided for a package that really needed one, such as where the specification declared subprograms. If a body was provided for a package that did not need one and the specification was later changed, the body became obsolete. Being optional, subsequent builds would not incorporate the body, unless it was manually recompiled. This affected simple packages that only declared types, constants or exceptions. Consider
package Optional_Body is
package body Optional_Body is
Global_Variable := Integer_Function;
In Ada 95, a library package can have a body only when required by a language rule; the above example is illegal in Ada 95. The pragma Elaborate_Body
can be used to cause a body to be required. Given the non-uniform functionality of program libraries, it is probably wise not to try to automatically detect and correct this incompatibility.
Indefinite Generic Parameters
In Ada 95, additional syntax is needed to indicate that a generic actual type is
allowed to be indefinite. In Ada 83, no indication is given in a generic formal
type declaration as to whether the actual needs to be definite, for example because
the body declares an uninitialized variable of the type. It is thus possible for a
legal instantiation to become illegal if the body is changed. An Ada 83 program,
where an indefinite type is used as a generic actual parameter is thus an illegal
Ada 95 program. Note that some predefined library units in Ada 83 used this feature and so are changed. An example is Sequential_IO
. In Ada 83, one could instantiate Sequential_IO
with type String
type Element_Type is private;
package Sequential_IO is ...
package String_IO is
This incompatibility cannot be avoided but an Ada 83 program can easily be made
a legal Ada 95 program. For example, the generic formal parameter of
is changed to type Element_Type(<>)
(Existing units like Sequential_IO
child units of Ada; compatibility is ensured by renamings.) Detection of the
incompatibility is straightforward. Manual correction is necessary to determine
whether restricting the actual to being constrained is acceptable.
In Ada 95, the exception Numeric_Error
is a renaming of Constraint_Error
. Checks that could raise Numeric_Error
in Ada 83 have been reworded to raise Constraint_Error
instead. Indeed, this change has been sanctioned by the ARG for existing Ada 83 implementations.
The alternative of deleting Numeric_Error was rejected because of the resulting incompatibility in programs using the recommended construction
when Numeric_Error | Constraint_Error
that avoids the confusion between the two exceptions in Ada 83. This construction is allowed in Ada 95 because of an additional rule that permits an exception to be mentioned more than once in the same handler. Programs having distinct separate handlers for Numeric_Error
when Constraint_Error => Action_1;
when Numeric_Error => Action_2;
are illegal in Ada 95. However, replacing Numeric_Error
by others in the above will result in an inconsistency since Numeric_Error
will be caught by the first handler in Ada 95 but by the second in Ada 83. Detection of the incompatibility is straightforward but manual correction will be necessary if Numeric_Error
is treated differently.
We have discussed the main incompatibilities between Ada 83 and Ada 95 and shown
how they may be overcome. It is clear that there are unlikely to be significant
transition issues for the vast majority of Ada 83 programs. Ada 95 has been
carefully designed to minimize incompatibilities while meeting the overall goals
of the requirements. For further details consult the comprehensive discussion in
Taylor, W.J. Ada Compatibility Guide, Version 6, in Ada Year Book 1995,
John Barnes is the author of the popular book Programming in Ada 95
published by Addison Wesley Longman. Readers may contact the author at
11 Albert Road
Reading RG4 7AN UK
Copyright 1998. IIT Research Institute
All rights assigned to the US Government (Ada Joint Program Office).
Permission to reprint this article, in whole or in part, is granted, provided
the AdaIC is acknowledged as the source.