[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E. Compatibility and Porting Guide

This chapter describes the compatibility issues that may arise between GNAT and other Ada 83 and Ada 95 compilation systems, and shows how GNAT can expedite porting applications developed in other Ada environments.

E.1 Compatibility with Ada 83  
E.2 Implementation-dependent characteristics  
E.3 Compatibility with Other Ada 95 Systems  
E.4 Representation Clauses  
E.5 Compatibility with DEC Ada 83  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.1 Compatibility with Ada 83

Ada 95 is designed to be highly upwards compatible with Ada 83. In particular, the design intention is that the difficulties associated with moving from Ada 83 to Ada 95 should be no greater than those that occur when moving from one Ada 83 system to another.

However, there are a number of points at which there are minor incompatibilities. The Ada 95 Annotated Reference Manual contains full details of these issues, and should be consulted for a complete treatment. In practice the following subsections treat the most likely issues to be encountered.

E.1.1 Legal Ada 83 programs that are illegal in Ada 95  
E.1.2 More deterministic semantics  
E.1.3 Changed semantics  
E.1.4 Other language compatibility issues  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.1.1 Legal Ada 83 programs that are illegal in Ada 95

Character literals
Some uses of character literals are ambiguous. Since Ada 95 has introduced Wide_Character as a new predefined character type, some uses of character literals that were legal in Ada 83 are illegal in Ada 95. For example:
 
   for Char in 'A' .. 'Z' loop ... end loop;
The problem is that 'A' and 'Z' could be from either Character or Wide_Character. The simplest correction is to make the type explicit; e.g.:
 
   for Char in Character range 'A' .. 'Z' loop ... end loop;

New reserved words
The identifiers abstract, aliased, protected, requeue, tagged, and until are reserved in Ada 95. Existing Ada 83 code using any of these identifiers must be edited to use some alternative name.

Freezing rules
The rules in Ada 95 are slightly different with regard to the point at which entities are frozen, and representation pragmas and clauses are not permitted past the freeze point. This shows up most typically in the form of an error message complaining that a representation item appears too late, and the appropriate corrective action is to move the item nearer to the declaration of the entity to which it refers.

A particular case is that representation pragmas cannot be applied to a subprogram body. If necessary, a separate subprogram declaration must be introduced to which the pragma can be applied.

Optional bodies for library packages
In Ada 83, a package that did not require a package body was nevertheless allowed to have one. This lead to certain surprises in compiling large systems (situations in which the body could be unexpectedly ignored by the binder). In Ada 95, if a package does not require a body then it is not permitted to have a body. To fix this problem, simply remove a redundant body if it is empty, or, if it is non-empty, introduce a dummy declaration into the spec that makes the body required. One approach is to add a private part to the package declaration (if necessary), and define a parameterless procedure called Requires_Body, which must then be given a dummy procedure body in the package body, which then becomes required. Another approach (assuming that this does not introduce elaboration circularities) is to add an Elaborate_Body pragma to the package spec, since one effect of this pragma is to require the presence of a package body.

Numeric_Error is now the same as Constraint_Error
In Ada 95, the exception Numeric_Error is a renaming of Constraint_Error. This means that it is illegal to have separate exception handlers for the two exceptions. The fix is simply to remove the handler for the Numeric_Error case (since even in Ada 83, a compiler was free to raise Constraint_Error in place of Numeric_Error in all cases).

Indefinite subtypes in generics
In Ada 83, it was permissible to pass an indefinite type (e.g. String) as the actual for a generic formal private type, but then the instantiation would be illegal if there were any instances of declarations of variables of this type in the generic body. In Ada 95, to avoid this clear violation of the methodological principle known as the "contract model", the generic declaration explicitly indicates whether or not such instantiations are permitted. If a generic formal parameter has explicit unknown discriminants, indicated by using (<>) after the type name, then it can be instantiated with indefinite types, but no stand-alone variables can be declared of this type. Any attempt to declare such a variable will result in an illegality at the time the generic is declared. If the (<>) notation is not used, then it is illegal to instantiate the generic with an indefinite type. This is the potential incompatibility issue when porting Ada 83 code to Ada 95. It will show up as a compile time error, and the fix is usually simply to add the (<>) to the generic declaration.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.1.2 More deterministic semantics

Conversions
Conversions from real types to integer types round away from 0. In Ada 83 the conversion Integer(2.5) could deliver either 2 or 3 as its value. This implementation freedom was intended to support unbiased rounding in statistical applications, but in practice it interfered with portability. In Ada 95 the conversion semantics are unambiguous, and rounding away from 0 is required. Numeric code may be affected by this change in semantics. Note, though, that this issue is no worse than already existed in Ada 83 when porting code from one vendor to another.

Tasking
The Real-Time Annex introduces a set of policies that define the behavior of features that were implementation dependent in Ada 83, such as the order in which open select branches are executed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.1.3 Changed semantics

The worst kind of incompatibility is one where a program that is legal in Ada 83 is also legal in Ada 95 but can have an effect in Ada 95 that was not possible in Ada 83. Fortunately this is extremely rare, but the one situation that you should be alert to is the change in the predefined type Character from 7-bit ASCII to 8-bit Latin-1.

range of Character
The range of Standard.Character is now the full 256 characters of Latin-1, whereas in most Ada 83 implementations it was restricted to 128 characters. Although some of the effects of this change will be manifest in compile-time rejection of legal Ada 83 programs it is possible for a working Ada 83 program to have a different effect in Ada 95, one that was not permitted in Ada 83. As an example, the expression Character'Pos(Character'Last) returned 127 in Ada 83 and now delivers 255 as its value. In general, you should look at the logic of any character-processing Ada 83 program and see whether it needs to be adapted to work correctly with Latin-1. Note that the predefined Ada 95 API has a character handling package that may be relevant if code needs to be adapted to account for the additional Latin-1 elements. The desirable fix is to modify the program to accommodate the full character set, but in some cases it may be convenient to define a subtype or derived type of Character that covers only the restricted range.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.1.4 Other language compatibility issues

`-gnat83 switch'
All implementations of GNAT provide a switch that causes GNAT to operate in Ada 83 mode. In this mode, some but not all compatibility problems of the type described above are handled automatically. For example, the new Ada 95 reserved words are treated simply as identifiers as in Ada 83. However, in practice, it is usually advisable to make the necessary modifications to the program to remove the need for using this switch. See 3.2.10 Compiling Different Versions of Ada.

Support for removed Ada 83 pragmas and attributes
A number of pragmas and attributes from Ada 83 have been removed from Ada 95, generally because they have been replaced by other mechanisms. Ada 95 compilers are allowed, but not required, to implement these missing elements. In contrast with some other Ada 95 compilers, GNAT implements all such pragmas and attributes, eliminating this compatibility concern. These include pragma Interface and the floating point type attributes (Emax, Mantissa, etc.), among other items.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2 Implementation-dependent characteristics

Although the Ada language defines the semantics of each construct as precisely as practical, in some situations (for example for reasons of efficiency, or where the effect is heavily dependent on the host or target platform) the implementation is allowed some freedom. In porting Ada 83 code to GNAT, you need to be aware of whether / how the existing code exercised such implementation dependencies. Such characteristics fall into several categories, and GNAT offers specific support in assisting the transition from certain Ada 83 compilers.

E.2.1 Implementation-defined pragmas  
E.2.2 Implementation-defined attributes  
E.2.3 Libraries  
E.2.4 Elaboration order  
E.2.5 Target-specific aspects  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2.1 Implementation-defined pragmas

Ada compilers are allowed to supplement the language-defined pragmas, and these are a potential source of non-portability. All GNAT-defined pragmas are described in the GNAT Reference Manual, and these include several that are specifically intended to correspond to other vendors' Ada 83 pragmas. For migrating from VADS, the pragma Use_VADS_Size may be useful. For compatibility with DEC Ada 83, GNAT supplies the pragmas Extend_System, Ident, Inline_Generic, Interface_Name, Passive, Suppress_All, and Volatile. Other relevant pragmas include External and Link_With. Some vendor-specific Ada 83 pragmas (Share_Generic, Subtitle, and Title) are recognized, thus avoiding compiler rejection of units that contain such pragmas; they are not relevant in a GNAT context and hence are not otherwise implemented.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2.2 Implementation-defined attributes

Analogous to pragmas, the set of attributes may be extended by an implementation. All GNAT-defined attributes are described in the GNAT Reference Manual, and these include several that are specifically intended to correspond to other vendors' Ada 83 attributes. For migrating from VADS, the attribute VADS_Size may be useful. For compatibility with DEC Ada 83, GNAT supplies the attributes Bit, Machine_Size and Type_Class.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2.3 Libraries

Vendors may supply libraries to supplement the standard Ada API. If Ada 83 code uses vendor-specific libraries then there are several ways to manage this in Ada 95:
  1. If the source code for the libraries (specifications and bodies) are available, then the libraries can be migrated in the same way as the application.
  2. If the source code for the specifications but not the bodies are available, then you can reimplement the bodies.
  3. Some new Ada 95 features obviate the need for library support. For example most Ada 83 vendors supplied a package for unsigned integers. The Ada 95 modular type feature is the preferred way to handle this need, so instead of migrating or reimplementing the unsigned integer package it may be preferable to retrofit the application using modular types.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2.4 Elaboration order

The implementation can choose any elaboration order consistent with the unit dependency relationship. This freedom means that some orders can result in Program_Error being raised due to an "Access Before Elaboration": an attempt to invoke a subprogram its body has been elaborated, or to instantiate a generic before the generic body has been elaborated. By default GNAT attempts to choose a safe order (one that will not encounter access before elaboration problems) by implicitly inserting Elaborate_All pragmas where needed. However, this can lead to the creation of elaboration circularities and a resulting rejection of the program by gnatbind. This issue is thoroughly described in C. Elaboration Order Handling in GNAT. In brief, there are several ways to deal with this situation:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2.5 Target-specific aspects

Low-level applications need to deal with machine addresses, data representations, interfacing with assembler code, and similar issues. If such an Ada 83 application is being ported to different target hardware (for example where the byte endianness has changed) then you will need to carefully examine the program logic; the porting effort will heavily depend on the robustness of the original design. Moreover, Ada 95 is sometimes incompatible with typical Ada 83 compiler practices regarding implicit packing, the meaning of the Size attribute, and the size of access values. GNAT's approach to these issues is described in E.4 Representation Clauses.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.3 Compatibility with Other Ada 95 Systems

Providing that programs avoid the use of implementation dependent and implementation defined features of Ada 95, as documented in the Ada 95 reference manual, there should be a high degree of portability between GNAT and other Ada 95 systems. The following are specific items which have proved troublesome in moving GNAT programs to other Ada 95 compilers, but do not affect porting code to GNAT.

Ada 83 Pragmas and Attributes
Ada 95 compilers are allowed, but not required, to implement the missing Ada 83 pragmas and attributes that are no longer defined in Ada 95. GNAT implements all such pragmas and attributes, eliminating this as a compatibility concern, but some other Ada 95 compilers reject these pragmas and attributes.

Special-needs Annexes
GNAT implements the full set of special needs annexes. At the current time, it is the only Ada 95 compiler to do so. This means that programs making use of these features may not be portable to other Ada 95 compilation systems.

Representation Clauses
Some other Ada 95 compilers implement only the minimal set of representation clauses required by the Ada 95 reference manual. GNAT goes far beyond this minimal set, as described in the next section.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.4 Representation Clauses

The Ada 83 reference manual was quite vague in describing both the minimal required implementation of representation clauses, and also their precise effects. The Ada 95 reference manual is much more explicit, but the minimal set of capabilities required in Ada 95 is quite limited.

GNAT implements the full required set of capabilities described in the Ada 95 reference manual, but also goes much beyond this, and in particular an effort has been made to be compatible with existing Ada 83 usage to the greatest extent possible.

A few cases exist in which Ada 83 compiler behavior is incompatible with requirements in the Ada 95 reference manual. These are instances of intentional or accidental dependence on specific implementation dependent characteristics of these Ada 83 compilers. The following is a list of the cases most likely to arise in existing legacy Ada 83 code.

Implicit Packing
Some Ada 83 compilers allowed a Size specification to cause implicit packing of an array or record. This could cause expensive implicit conversions for change of representation in the presence of derived types, and the Ada design intends to avoid this possibility. Subsequent AI's were issued to make it clear that such implicit change of representation in response to a Size clause is inadvisable, and this recommendation is represented explicitly in the Ada 95 RM as implementation advice that is followed by GNAT. The problem will show up as an error message rejecting the size clause. The fix is simply to provide the explicit pragma Pack, or for more fine tuned control, provide a Component_Size clause.

Meaning of Size Attribute
The Size attribute in Ada 95 for discrete types is defined as being the minimal number of bits required to hold values of the type. For example, on a 32-bit machine, the size of Natural will typically be 31 and not 32 (since no sign bit is required). Some Ada 83 compilers gave 31, and some 32 in this situation. This problem will usually show up as a compile time error, but not always. It is a good idea to check all uses of the 'Size attribute when porting Ada 83 code. The GNAT specific attribute Object_Size can provide a useful way of duplicating the behavior of some Ada 83 compiler systems.

Size of Access Types
A common assumption in Ada 83 code is that an access type is in fact a pointer, and that therefore it will be the same size as a System.Address value. This assumption is true for GNAT in most cases with one exception. For the case of a pointer to an unconstrained array type (where the bounds may vary from one value of the access type to another), the default is to use a "fat pointer", which is represented as two separate pointers, one to the bounds, and one to the array. This representation has a number of advantages, including improved efficiency. However, it may cause some difficulties in porting existing Ada 83 code which makes the assumption that, for example, pointers fit in 32 bits on a machine with 32-bit addressing.

To get around this problem, GNAT also permits the use of "thin pointers" for access types in this case (where the designated type is an unconstrained array type). These thin pointers are indeed the same size as a System.Address value. To specify a thin pointer, use a size clause for the type, for example:

 
type X is access all String;
for X'Size use Standard'Address_Size;

which will cause the type X to be represented using a single pointer. When using this representation, the bounds are right behind the array. This representation is slightly less efficient, and does not allow quite such flexibility in the use of foreign pointers or in using the Unrestricted_Access attribute to create pointers to non-aliased objects. But for any standard portable use of the access type it will work in a functionally correct manner and allow porting of existing code. Note that another way of forcing a thin pointer representation is to use a component size clause for the element size in an array, or a record representation clause for an access field in a record.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.5 Compatibility with DEC Ada 83

The VMS version of GNAT fully implements all the pragmas and attributes provided by DEC Ada 83, as well as providing the standard DEC Ada 83 libraries, including Starlet. In addition, data layouts and parameter passing conventions are highly compatible. This means that porting existing DEC Ada 83 code to GNAT in VMS systems should be easier than most other porting efforts. The following are some of the most significant differences between GNAT and DEC Ada 83.

Default floating-point representation
In GNAT, the default floating-point format is IEEE, whereas in DEC Ada 83, it is VMS format. GNAT does implement the necessary pragmas (Long_Float, Float_Representation) for changing this default.

System
The package System in GNAT exactly corresponds to the definition in the Ada 95 reference manual, which means that it excludes many of the DEC Ada 83 extensions. However, a separate package Aux_DEC is provided that contains the additional definitions, and a special pragma, Extend_System allows this package to be treated transparently as an extension of package System.

To_Address
The definitions provided by Aux_DEC are exactly compatible with those in the DEC Ada 83 version of System, with one exception. DEC Ada provides the following declarations:

 
TO_ADDRESS (INTEGER)
TO_ADDRESS (UNSIGNED_LONGWORD)
TO_ADDRESS (universal_integer)

The version of TO_ADDRESS taking a universal integer argument is in fact an extension to Ada 83 not strictly compatible with the reference manual. In GNAT, we are constrained to be exactly compatible with the standard, and this means we cannot provide this capability. In DEC Ada 83, the point of this definition is to deal with a call like:

 
TO_ADDRESS (16#12777#);

Normally, according to the Ada 83 standard, one would expect this to be ambiguous, since it matches both the INTEGER and UNSIGNED_LONGWORD forms of TO_ADDRESS. However, in DEC Ada 83, there is no ambiguity, since the definition using universal_integer takes precedence.

In GNAT, since the version with universal_integer cannot be supplied, it is not possible to be 100% compatible. Since there are many programs using numeric constants for the argument to TO_ADDRESS, the decision in GNAT was to change the name of the function in the UNSIGNED_LONGWORD case, so the declarations provided in the GNAT version of AUX_Dec are:

 
function To_Address (X : Integer) return Address;
pragma Pure_Function (To_Address);

function To_Address_Long (X : Unsigned_Longword)
 return Address;
pragma Pure_Function (To_Address_Long);

This means that programs using TO_ADDRESS for UNSIGNED_LONGWORD must change the name to TO_ADDRESS_LONG.

Task_Id values
The Task_Id values assigned will be different in the two systems, and GNAT does not provide a specified value for the Task_Id of the environment task, which in GNAT is treated like any other declared task.

For full details on these and other less significant compatibility issues, see appendix E of the Digital publication entitled DEC Ada, Technical Overview and Comparison on DIGITAL Platforms.

For GNAT running on other than VMS systems, all the DEC Ada 83 pragmas and attributes are recognized, although only a subset of them can sensibly be implemented. The description of pragmas in this reference manual indicates whether or not they are applicable to non-VMS systems.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Mail Server on June, 15 2005 using texi2html