![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Ada 83 to Ada 95 Transition Code Changes This section addresses issues that come up specifically when moving from Ada 83 to Ada 95, or more precisely, from Apex Ada 83 to Apex Ada 95. Typically the changes are purely due to Ada dialect issues, but in some cases the issues are specifically due to the Apex implementations.
The following topics are covered here:
- Pragma.1.ada
- System.Address incompatibilities
- Derived Type and Representation Specification Incompatibilities
- Character literal type not resolvable
- Use of null strings ("") for user-defined string types fails (bug)
Pragma.1.adaThere are four runtimes, ts0 through ts3. Higher numbers support more complex scenarios, and thus have a higher overhead. For optimal speed, use the most restrictions appropriate for the code. Place this file, pragma.1.ada in every view used in a link.
The following four restrictions force ts2, ts1 or ts0:
pragma Restrictions (No_Abort_Statements); pragma Restrictions (Max_Asynchronous_Select_Nesting => 0); pragma Restrictions (No_Requeue_Statements); pragma Restrictions (No_Dynamic_Priorities);
Adding the following restriction forces ts1 or ts0:
pragma Restrictions (No_Terminate_Alternatives);
Adding the following restriction forces ts0:
pragma Restrictions (No_Tasking);
The following only restrict usage; they have no effect on speed:
pragma Restrictions (No_Asynchronous_Control); pragma Restrictions (No_Task_Hierarchy);
The following should be enabled for maximum speed (at the sacrifice of runtime checking of range and other constraints). This is equivalent to the "-S" switch for VADS or "-O3 -gnatp" for GNAT:
pragma Suppress (All_Checks);
System.Address incompatibilitiesThe System package has a different structure and layout in Ada 95 compared to Ada 83. In particular, address arithmetic with integers is different, requiring changes at every usage. It is possible to define a package which provides Ada 83 equivalent functions in such a way that optimization should remove any overhead, but we suggest converting over to the Ada 95 approach, as it provides a better abstraction.
Ada83
Package System defines address and integer mixing functions:
type Address is private; subtype Address_Sized_Integer is Standard.Integer; function To_Address (Value : Address_Sized_Integer) return Address; function To_Integer (Value : Address) return Address_Sized_Integer; function "+" (Left : Address; Right : Integer) return Address; function "+" (Left : Integer; Right : Address) return Address; function "-" (Left : Address; Right : Integer) return Address; function "+" (Left : Address; Right : Long_Integer) return Address; function "+" (Left : Long_Integer; Right : Address) return Address; function "-" (Left : Address; Right : Long_Integer) return Address; function "<" (Left, Right : Address) return Boolean; function "<=" (Left, Right : Address) return Boolean; function ">" (Left, Right : Address) return Boolean; function ">=" (Left, Right : Address) return Boolean; function "-" (Left : Address; Right : Address) return Integer; function "+" (I : Address_Sized_Unsigned) return Address; function Address'Ref (I : Address_Sized_Unsigned) return Address renames "+"; Address_Zero : constant Address; Null_Address : constant Address; No_Addr : constant Address;Ada95
Package System only defines address and a few constants:
type Address is private; Null_Address : constant Address; Storage_Unit : constant := 8; Word_Size : constant := 4 * Storage_Unit; Memory_Size : constant := +(2 ** 31) - 1; -- Address comparison function "<" (Left, Right : Address) return Boolean; function "<=" (Left, Right : Address) return Boolean; function ">" (Left, Right : Address) return Boolean; function ">=" (Left, Right : Address) return Boolean; function "=" (Left, Right : Address) return Boolean;Package System.Storage_Elements defines remaining address and integer mixings, but uses a integer derived type, not a sub-type of integer:
type Storage_Offset is range Min_Int .. Max_Int; -- Address Arithmetic function "+" (Left : Address; Right : Storage_Offset) return Address; function "+" (Left : Storage_Offset; Right : Address) return Address; function "-" (Left : Address; Right : Storage_Offset) return Address; function "-" (Left, Right : Address) return Storage_Offset; function "mod" (Left : Address; Right : Storage_Offset) return Storage_Offset; -- Conversion to/from integers type Integer_Address is mod 2 ** 32; function To_Address (Value : Integer_Address) return Address; function To_Integer (Value : Address) return Integer_Address;All usages must be changed accordingly. First, any "with"s must be modified:
Ada 83: with System; Ada 95: with System; with System.Storage_Elements;
Then any importation must be changed. If a use clause is in force, then it must be modified to specify use of
System.Storage_Elements
as well. If operators are imported using renames clauses, then we recommend also importing theStorage_Offset
type:
Ada 83: function "+" (A : System.Address; I : Integer ) return Address renames System."+"; Ada 95: subtype Offset is System.Storage_Elements.Storage_Offset ; function "+" (A : System.Address; I : Offset ) return Address renames System.Storage_Elements."+";Finally, any locations where the functions are used must be modified to convert the integer type to the
Offset
type defined:
A : Address := <some_address> ; B : Address := <some_address> ; I : Integer := <some_integer> ; Ada 83: A := A + I ; I := A - B ; Ada 95: A := A + Offset(i) ; I := Integer( A - B ) ;This is relatively easy to do using the Apex GUI. Simply analyze the code, and all the appropriate "+" operators with problems will be highlighted. It is simple to then put "Offset(" right after the "+", and put a closing ")" at the appropriate end of the integer expression. Similarly, all "-" results can quickly be enclosed in a type conversion to Integer.
An alternative is to define a package that defines the same operations as the System package in Ada 83, and trust inlining and optimizations to eliminate all overhead. All places that use System must be changed, but if there was copious use of use clauses, then simply adding a with and use for this new package should suffice to convert the code. Functions in that package should minimally include:
function "+" (L : System.Address; R : Integer ) return System.Address ; function "-" (L,R : System.Address ) return Integer ; function To_Integer (Value : in System.Address ) return Integer ; function To_Address ( Value : in Integer ) return System.Address ;
Derived Type and Representation Specification IncompatibilitiesConsider the following small example code:
package Pkg_Parent is type Base_Type is new Integer range 0 .. 32; function User_Function (D : Base_Type) return Integer; end Pkg_Parent; with Pkg_Parent; package Pkg_Child is type Der_Type is new Pkg_Parent.Base_Type; for Der_Type'Size use 16; end Pkg_Child; with Pkg_Parent; package pkg_child2 is type Der_Type2 is new Pkg_Parent.Base_Type; end Pkg_Child2;
Ada83
In Ada 83, the above code compiles and works fine. Note, however, that function "User_Function" is not defined for either
Der_Type
orDer_Type2
.Ada95
In Ada 95, the above code produces the following error when compiling
Pkg_Child
:
>>> Line 4: for Der_Type'Size use 16; *** Der_Type's parent type has derivable subprograms [RM_95 13.1(10)]In Ada 95, both
Der_Type
andDer_Type2
have appropriate User_function functions defined and available. This is because in Ada 95 a derived type inherits all operations of the parent type.The problem then, when converting Ada 83 code to Ada 95, is to disconnect the derived types from the primitive operations ("Image") in the parent package. This is conveniently achieved by defining a second type in the parent package, either a parent base type, or a derived child type, depending on usage within the application. Typically the parent type has more places where it is used, so it becomes desirable to create a parent base type as follows:
package Pkg_Parent is type Base_Type_Base is new Integer range 0 .. 32; type Base_Type is new Base_Type_Base; function User_Function (D : Base_Type) return Integer; end Pkg_Parent; with Pkg_Parent; package Pkg_Child is type Der_Type is new Pkg_Parent.Base_Type_Base; for Der_Type'Size use 16; end Pkg_Child; with Pkg_Parent; package Pkg_Child2 is type Der_Type2 is new Pkg_Parent.Base_Type_Base; end Pkg_Child2;
With this change, each derived type must be changed to point to the base type, which has no associated derived subprograms. In the unlikely case that there are a lot of derived type usage points, the original name can be used for the base type and a new name used for the child type within
Pkg_Parent
. If that is done, then all occurrences within thePkg_Parent
package must be changed appropriately, and any external usages changed as well.
Character literal type not resolvableThe following code is invalid in Ada 95 and valid in Ada 83:
package Test is type Search_List is array ('0' .. '9') of Integer; end Test ;
Note that in Apex, the error message produced is not very helpful:
>>> Line 2: type Search_List is array ('0' .. '9') of Integer *** '0' is not of a discrete type *** '9' is not of a discrete type
The error message indicates a problem with the index type, but fails to note that it is overload resolution that is the problem, not whether a character literal can be discrete.
The problem is that in Ada 95 there are two possible types for character literals,
Character
andWide_Character
. The context does not permit the overloading to be resolved. The simple fix is to add an explicit type:
package Test is type Search_List is array (Character range '0' .. '9') of Integer; end Test ;It is also possible to use a subtype in this case to introduce the selected type:
package Test is subtype Index is Character range '0'..'9' ; type Search_List is array (Index) of Integer; end Test ;
Use of null strings ("") for user-defined string types fails (bug)For user-defined string types (arrays of enumerated types that include character literals), the use of the null string ("") causes an compilation error in Ada 95. For example, the following code:
with Text_Io; procedure Null_String is type Index is new Positive range 1..64; type Arr is array (Index range <>) of Character; Null_Arr : constant Arr := ""; Text : Arr (1 .. 6) := "Ran ok"; begin Text_Io.Put_Line (String (Text & Null_Arr)); end Null_String;
produces the following compilation errors with Apex Ada 95:
>>> Line 5: Null_Arr : constant Arr := ""; *** "" is disallowed since it is static and will raise Constraint_Error [RM_95 4.9(34)] >>> Line 8: Text_Io.Put_Line (String (Text & Null_Arr)); *** Null_Arr is disallowed since it is static and will raise Constraint_Error [RM_95 4.9(34)]
The same code compiles and runs without error under VADS and Apex Ada 83. This bug in Apex Ada 95 can be worked around simply by breaking the index type declaration into two steps as in the following workaround code:
with Text_Io; procedure Null_String is type Index_Base is new Positive; subtype Index is Index_Base range 1 .. 64; type Arr is array (Index range <>) of Character; Null_Arr : constant Arr := ""; Text : Arr (1 .. 6) := "Ran ok"; begin Text_Io.Put_Line (String (Text & Null_Arr)); end Null_String;
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |