



4   Upward Compatibility



A major design goal of Ada 9X is to avoid or at least
minimize the need for modifying the existing base of Ada 83
software to make it compatible with Ada 9X.  This involves
not only pursuing upward compatibility but also preserving
implementation-dependent behavior that can currently be
relied upon.  In common with the experience of revising
other language standards, it is infeasible to guarantee 100%
compatibility.
   Other languages have been more or less successful in
meeting this goal.  For example, COBOL 83 has been very
successful in achieving upward compatibility with COBOL 74.
Nevertheless some minor incompatibilities were introduced
which affect existing programs.  For example, IS_ALPHABETIC,
accepts upper and lower case in the new COBOL standard.  The
transition from C to ANSI C and from there to C++ has also
caused incompatibilities, for example C++ requires all
procedure definitions in old-style C to be modified.
   In the Ada 9X design, a very conservative approach has
been adopted.  The few incompatibilities that exist can be
dealt with in a simple mechanical way.  For example, the
introduction of a small number of reserved words requires
their replacement in any program using them as identifiers.
Extensive surveys of existing code show few programs to be
affected.  Most of the other incompatibilities involve
obscure or pathological programming styles which are
expected to appear very infrequently in existing code.
   The great majority of programs will not be significantly
affected by these changes - the most likely
incompatibilities being automatically detected at
compilation time.  Moreover, tools are being developed to
aid in the reliable detection of any problems and thereby
smooth the process of transition.
   Only five incompatibilities are considered likely to
occur in normal programs.  They are as follows

New reserved words - Ada 9X has added five new reserved
     words to the language.

Type Character has 256 positions - In Ada 83, the type
     Character originally had 128 positions.  In Ada 9X, it
     has 256 positions.

Body required for library unit packages - In Ada 9X, all
     library packages require a body, even if they were
     optional in Ada 83.

Generic contract model enforcement - An Ada 83 generic
     contract model violation has been overcome in Ada 9X by
     a change of syntax.

Numeric_Error removed from language - The declaration for
     Numeric_Error has been removed from package Standard
     for Ada 9X.
   
   These incompatibilities cause a legal Ada 83 program to
be an illegal Ada 9X program and hence are detected at
compile time.  They are described in more detail in the
ensuing sections.  In each case we give an example of the
incompatibility, an indication of how it can be avoided in
existing Ada 83 programs and the possibility of its
automatic detection and removal.
   The remaining incompatibilities which are considered very
unlikely to occur in normal programs are briefly considered
in Section 4.6.
   The reader should note that we say that an
incompatibility is consistent if the worst that can happen
is that a legal Ada 83 program becomes illegal in Ada 9X and
thus fails to compile.  An incompatibility is said to be
inconsistent if the program can remain legal but have a
different meaning.


4.1  Reserved Words

Five new reserved words are introduced in Ada 9X: aliased,
protected, requeue, tagged, and until.
   Two alternatives to new reserved words were considered: a
new concept of unreserved keywords or the use of
combinations of existing reserved words.  Neither of these
options was considered preferable to the transitory
inconvenience caused by the introduction of the new reserved
words.
   An Ada 83 program that uses any of these words as
identifiers is an illegal Ada 9X program.  For example, the
following fragment of Ada 83 will fail to compile in Ada 9X
because it uses two of the new reserved words

   Protected: Boolean := False;
   
   procedure Requeue(The_Activity: Activity; 
                         On_Queue:   Queue);

   Avoidance is clearly straightforward - avoid use of these
five words as identifiers.  Detection of the incompatibility
is also straightforward.  Automatic correction is
problematic - to ensure that a name change is valid requires
significant analysis especially if the identifier is the
name of a library unit, or occurs in a package specification
for which use clauses occur.
   However, Ada 9X allows identifiers to have a trailing
underline and so it is possible, for example, to
systematically replace Requeue by Requeue_ in all contexts.


4.2  Type Character

In Ada 9X, the type Character has 256 positions.  In Ada 83,
it has 128 positions.
   Although suitable for English-speaking nations, a
character type based on ASCII is inappropriate for most of
Europe.  ISO has defined a number of 256 character standards
such as Latin 1 and Latin 2.  This change to the language
thus accommodates non-English speaking nations.
   An Ada 83 program could be an illegal Ada 9X program if
it has a case statement or an array indexed by Character,
but it could be a legal Ada 9X program with different
semantics if it relies on the position number or value of
Character'Last.  For example

   type Char_Kind is (Numeric, Alphabetic, Other);
   
   Kind_Array: array (Character) of Char_Kind := -- (1)
                 ('0' .. '9' => Numeric,
                  'A' .. 'Z' | 'a' .. 'z' => Alphabetic,
                  others => Other);
   
   case Char is                                  -- (2)
      when Character'Val(0) .. Character'Val(63) => ...
      when Character'Val(64) .. Character'Val(127) => ...
   end case;
   
   I: Integer := Character'Pos(Character'Last);  -- (3)

   Declaration (1) is legal in Ada 9X but probably does not
achieve the desired effect.  Statement (2) is illegal in Ada
9X and will be detected at compilation.  Statement (3)
illustrates a situation where the program will still execute
but have a different effect in Ada 9X (it is inconsistent).
   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 behavior is acceptable for these
extra characters, use of an others choice, whilst ensuring a
legal (but bad style) Ada 9X program might cause
unacceptable behavior.
   Detection of the consistent incompatibilities is
straightforward; detection that an inconsistency may arise
is possible.  Manual correction is necessary to determine
whether the required semantics of the program are those
defined by Ada 9X.
   Finally, it should be noted that the ISO Working Group
with responsibility for maintaining the Ada standard, has
decreed that this change can be introduced into Ada 83
compilers, so this will increasingly become an Ada 83
portability problem as more implementations support 256
characters.


4.3  Library Package Bodies

In Ada 9X, all library unit packages are allowed to have a body only
if required by language rules.  This avoids a nasty and not so rare error.
   In Ada 83, a body need only be provided for a package
that really needs one, such as where the specification
contains subprogram or task declarations.  If a body is
provided for a library package that does not need a body,
then if the package specification is subsequently changed,
the body becomes obsolete.  However, since it is optional,
subsequent builds incorporating the package will not
incorporate the body, unless it is manually recompiled.
This obviously affects packages, for example, that only
declare types, constants and/or exceptions, a very common
occurrence.  As a trivial example consider

   package Optional_Body is
      Global_Variable: Integer;
   end Optional_Body;
   
   -----------------------------------------
   
   with Integer_Function;
   package body Optional_Body is
   begin
      Global_Variable := Integer_Function;
   end Optional_Body;

The solution adopted is simply to allow a body for library unit
packages only when required.  The pragma Elaborate_Body can be used
to cause the requirement.
   Given the non-uniform functionality of program libraries
and sublibraries, it is probably wise not to try to
automatically detect, let alone correct, this
incompatibility.


4.4  Unconstrained Generic Types

In Ada 9X, additional syntax is needed to indicate that a
generic actual type is allowed to be unconstrained without
defaults.  Otherwise, the actual must be constrained or have
defaults.
   In Ada 83, no indication is given in a generic formal
type declaration as to whether the actual needs to be
constrained, for example because the body declares a
variable for the type.  It is thus possible for a legal
instantiation to become illegal if the body is changed.
   An Ada 83 program, where an unconstrained type is used as
a generic actual parameter is an illegal Ada 9X program.
   It is interesting to note that some predefined library
units in Ada 83 use this feature and so are changed.
Examples are Unchecked_Conversion and Unchecked_Deallocation
and also Sequential_IO.
   In Ada 83, it is legal to instantiate Sequential_IO with
type String, thus

   with IO_Exceptions;
   generic
      type Element_Type is private;
   package Sequential_IO is ...
   
   ------------------------------------------------------
   
   with Sequential_IO;
   package String_IO is 
   new Sequential_IO (Element_Type => String);

   There is no way to avoid this incompatibility but an Ada
83 program can easily be made a legal Ada 9X program.  For
example, the declaration of Sequential_IO is simply changed
to

   generic
      type Element_Type (<>) is private;
   package Sequential_IO is ...

   Detection of the incompatibility is straightforward.
Manual correction is necessary to determine whether
restricting the actual to being constrained is acceptable.


4.5  Numeric Error

In Ada 9X, the exception Numeric_Error is no longer declared
in the package Standard.
   The checks that could cause Numeric_Error to be raised in
Ada 83 have all been reworded to cause Constraint_Error to
be raised instead.  Indeed, this change has been sanctioned
by the Ada Rapporteur Group and encouraged in existing Ada
83 implementations.
   Removing the declaration from package Standard avoids an
inconsistency by ensuring that code that catches
Numeric_Error does not remain in the source; it also avoids
leaving an unused declaration in package Standard - a source
of potential confusion in the future.
   The removal of Numeric_Error will naturally cause an
incompatibility if, for example, a program has mentioned
Numeric_Error in an exception handler such as

   when Numeric_Error | Constraint_Error => Some_Action;

which is the currently recommended interim way of avoiding
the confusion between Numeric_Error and Constraint_Error in
Ada 83.
   An (obscure) inconsistency can be caused if Numeric_Error
is declared in a use-visible package as in the following
contrived example

   package Num_Err is
      Numeric_Error: exception;
   end Num_Err;
   
   with Num_Err; use Num_Err;
   
   package P is
   ...
      when Numeric_Error | Constraint_Error => Some_Action;
   ...
   end P;

   In Ada 83, Numeric_Error in the handler refers to
Standard.Numeric_Error.  In Ada 9X, it refers to
Num_Err.Numeric_Error.  So an occurrence of
Num_Err.Numeric_Error could be caught by different handlers
in Ada 83 and Ada 9X.
   Attempts to avoid the problem automatically are unwise
since they are likely to lead to obscure Ada 9X programs
such as the above.
   Detection of occurrences of Standard.Numeric_Error is
straightforward.  Automatic correction is possible, by
removing the occurrence of Numeric_Error, but perhaps should
be confined to handlers that treat Constraint_Error
identically to Numeric_Error as in the example.
   Finally, note that the ruling that Constraint_Error
should be raised wherever the language specifies
Numeric_Error is expected to be reclassed as a binding
interpretation for Ada 83.  It is then possible that
Numeric_Error will subsequently be removed from the Ada 83
package Standard as well.  This incompatibility will then
also become an Ada 83 issue as in the case of the type
Character discussed in Section 4.2.


4.6  Other Incompatibilities

It is considered that the remaining incompatibilities will
be unlikely to occur in normal programs - the Ada 83
semantics being known only to the most erudite of Ada
programmers.
   The remaining upward incompatibilities will now be
described briefly.  They are grouped according to whether
they result in a legal Ada 9X program but with different
semantics; whether they would be detectable by an Ada 9X
compiler and so on.


4.6.1  Unlikely Inconsistencies

These incompatibilities cause a change in the runtime
behavior, but they are not thought likely to occur in normal
programs.

Derived type inherits all operations of parent - In Ada 9X a
     derived type inherits all its parent's primitive
     operations previously declared in the same declarative
     part.  In Ada 83, it did not.

Default 'Small for fixed point types - In Ada 83, the
     default value of T'Small was defined to be the largest
     power of two not exceeding T'Delta.  In Ada 9X, it is
     allowed to be a smaller power of two.

Evaluation order of generic actual parameters - The order of
     evaluation is arbitrary in Ada 9X.


4.6.2  Unlikely Incompatibilities

These incompatibilities cause a legal Ada 83 program to be
an illegal Ada 9X program and hence are detectable at
compile time.  It is not thought likely that existing Ada 83
programs will be affected.

Bad pragmas illegal - In Ada 83, a pragma with an error in
     its arguments is ignored.  In Ada 9X, it makes the
     compilation illegal.

T'Base not defined for composite types - In Ada 9X, T'Base
     is not defined for a composite type T.

Wide_Character shares all character literals - As a result
     of adding types Wide_Character and Wide_String to
     package Standard, Ada 83 character literals are always
     overloaded and Ada 83 string literals are always
     overloaded.

Definition of forcing occurrences tightened - In Ada 83,
     range constraints on a type after its declaration and
     in occurrences in pragmas were not treated as forcing
     occurrences.  In Ada 9X they are.

Real attributes replaced - The Ada 83 attributes for a real
     type T (such as T'Small) have been replaced by Ada 9X
     attributes defined in the Numerics Annex.

Static matching of subtypes - In Ada 9X, matching of
     subtypes is now performed statically instead of at
     runtime (as in Ada 83) in array conversions and generic
     instantiations.

Functions returning local variables containing tasks - In
     Ada 83 it is erroneous to return a variable containing
     a local task - in Ada 9X it is illegal or raises
     Program_Error if a function with a result type with a
     task subcomponent returns a local variable.

Preference for universal numeric operators - The overload
     resolution rules have been changed to simplify them and
     remove occurrences of the so-called Beaujolais effect.

Generic contract model enforcement - Some Ada 83 generic
     contract model violations have been overcome in Ada 9X
     by assuming the worst case within a generic body.

Append_Mode added to File_Mode enumeration - The type
     File_Mode in packages Sequential_IO and Text_IO has an
     extra literal, Append_Mode.

New identifiers added to package Standard - New identifiers
     in package Standard may clash with existing use-visible
     identifiers.


4.6.3  Implementation Dependent Incompatibilities

These incompatibilities only arise with some
implementations.  They occur either as a result of
tightening up Ada semantics or where an Ada 83
implementation has used an identifier now predefined in Ada
9X.  In the latter case, an inconsistency could occur if the
Ada 83 use of the identifier is compatible with the Ada 9X
use, though this is unlikely.

Rounding from Real to Integer is deterministic - Rounding is
     now defined as away from zero if the real number is
     midway between two integers.

New identifiers added to package System - New identifiers
     may introduce illegalities into a unit having a use
     clause for package System.

Configuration pragmas removed - Three pragmas (related to
     package System) have been removed but can still be
     supported.

Numeric_Error no longer raised - The recommended Ada 83
     behavior (to raise Constraint_Error instead) is
     mandated in Ada 9X.

New pragmas defined - The names of new pragmas may clash
     with implementation-defined pragmas.

New attributes defined - The names of new attributes may
     clash with implementation-defined attributes.

New library units defined - The names of new (language-
     defined) library units may clash with user-defined or
     implementation-defined library units.


4.6.4  Error Incompatibilities

These incompatibilities only occur in programs containing
runtime errors, either detectable (an exception is raised)
or undetectable (the execution is erroneous).

Exceeding 'First or 'Last of an unconstrained floating point
     type - The 'First and 'Last of a floating point type
     declared without a range constraint are treated as
     minimum bounds and may be exceeded without causing
     Constraint_Error provided that the mathematically
     correct result is returned.

Dependent compatibility checks performed on object
     declaration - In Ada 83, dependent compatibility checks
     are performed on subtype declaration.  In Ada 9X, they
     are performed on object declaration.

Implicit array subtype conversion - Ada 9X allows sliding in
     more situations than did Ada 83, so Constraint_Error
     might not be raised as in Ada 83.

Illegal to use value of deferred constant - In Ada 83 it is
     erroneous to use the value of a deferred constant
     before it is set.  In Ada 9X it is illegal.


4.7  Conclusion

This chapter has outlined the incompatibilities between Ada
83 and Ada 9X.  As we have seen, the small number that are
likely to occur in practice are easily overcome.  The
remainder are unlikely to be encountered in normal programs
but have been mentioned for completeness.  For further
details the reader should consult the comprehensive
discussion in [Taylor 92] upon which this chapter has been
based.
   In conclusion, it is clear that there are unlikely to be
significant transition issues for the vast majority of Ada
83 programs.  Ada 9X has been carefully designed to minimize
incompatibilities while meeting the overall goals of the
requirements.
