[Ada Information Clearinghouse]

Ada '83 Quality and Style:

Guidelines for Professional Programmers

Copyright 1989, 1991,1992 Software Productivity Consortium, Inc., Herndon, Virginia.

CHAPTER 7: Portability

7.1 Fundamentals

This section introduces some generally applicable principles of writing portable Ada programs. It includes guidelines about the assumptions you should make with respect to a number of Ada features and their implementations and guidelines about the use of other Ada features to ensure maximum portability.
In this section...
7.1.1 Global Assumptions
7.1.2 Actual Limits
7.1.3 Comments
7.1.4 Main Subprogram
7.1.5 Encapsulating Implementation Dependencies
7.1.6 Implementation-Added Features
Summary of Guidelines from this section


7.1.1 Global Assumptions

guideline

instantiation

These are minimum values (or minimum precision in the case of Duration'Small) that a project or application might assume that an implementation provides. There is no guarantee that a given implementation provides more than the minimum, so these would be treated by the project or application as maximum values also.

rationale

Some assumptions must be made with respect to certain implementation dependent values. The exact values assumed should cover the majority of the target equipment of interest. Choosing the lowest common denominator for values improves portability.

note

Of the microcomputers currently available for incorporation within embedded systems, 16-bit and 32-bit processors are prevalent. Although 4-bit and 8-bit machines are still available, their limited memory addressing capabilities make them unsuited to support Ada programs of any size. Using current representation schemes, 6 decimal digits of floating point accuracy implies a representation mantissa at least 21 bits wide, leaving 11 bits for exponent and sign within a 32-bit representation. This correlates with the data widths of floating point hardware currently available for the embedded systems market. A 32-bit minimum on fixed-point numbers correlates with the accuracy and storage requirements of floating point numbers.

The 72-column limit on source lines in the example is an unfortunate hold-over from the days of Hollerith punch cards with sequence numbers. There may still be machinery and software used in manipulating source code that are bound to assumptions about this maximum line length. The 16-bit example for Universal_Integer expressions matches that for Integer storage.

The values for the range and accuracy of values of the predefined type Duration are the limits expressed in the Ada Language Reference Manual (Department of Defense 1983, Section 9.6). You should not expect an implementation to provide a wider range or a finer granularity.

Language Ref Manual references: 3.5.4 Integer Types, 3.5.6 Real Types, 3.5.9 Fixed Point Types, 9.6 Delay Statements, Duration, and Time, C Predefined Language Environment, F Implementation-Dependent Characteristics


7.1.2 Actual Limits

guideline

rationale

The Ada model may not match exactly with the underlying hardware, so some compromises may have been made in the implementation. Check to see if they could affect your program. Particular implementations may do "better" than the Ada model requires while some others may be just minimally acceptable. Arithmetic is generally implemented with a precision higher than the storage capacity (this is implied by the Ada type model for floating point). Different implementations may behave differently on the same underlying hardware.

Language Ref Manual references: 3.5.4 Integer Types, 3.5.6 Real Types, F Implementation-Dependent Characteristics


7.1.3 Comments

guideline

example

------------------------------------------------------------------------ 
package Memory_Mapped_IO is

   -- WARNING - This package is implementation specific. 
   -- It uses absolute memory addresses to interface with the I/O 
   -- system. It assumes a particular printer's line length. 
   -- Change memory mapping and printer details when porting.
   
   Printer_Line_Length : constant := 132;
   
   type Data is array (1 .. Printer_Line_Length) of Character;
   
   procedure Write_Line (Line : in     Data);
   
end Memory_Mapped_IO;

------------------------------------------------------------------------ 
with System; 
package body Memory_Mapped_IO is

   --------------------------------------------------------------------- 
   procedure Write_Line (Line : in     Data) is
   
      Buffer : Data; 
      for Buffer use at System.Physical_Address(16#200#);
      
   begin  -- Write_Line 
       -- perform output operation through specific memory locations. 
       ... 
   end Write_Line; 
   ---------------------------------------------------------------------
   
end Memory_Mapped_IO; 
------------------------------------------------------------------------

rationale

Explicitly commenting each breach of portability will raise its visibility and aid in the porting process. A description of the non-portable feature's expectations covers the common case where vendor documentation of the original implementation is not available to the person performing the porting process.

Language Ref Manual references: 2.7 Comments, 6.1 Subprogram Declarations, 7.2 Package Specifications and Declarations, 9.1 Abort Statements, F Implementation-Dependent Characteristics


7.1.4 Main Subprogram

guideline

rationale

The Ada Language Reference Manual (Department of Defense 1983) places very few requirements on the main subprogram. Assume the simplest case will increase portability. That is, assume you may only use a parameterless procedure as a main program.

Some operating systems are capable of acquiring and interpreting returned integer values near zero from a function, but many others cannot. Further, many real-time, embedded systems will not be designed to terminate, so a function or a procedure having parameters with modes out or in out will be inappropriate to such applications.

This leaves procedures with in parameters. Although some operating systems can pass parameters in to a program as it starts, others cannot. Also, an implementation may not be able to perform type checking on such parameters even if the surrounding environment is capable of providing them.

note

Real-time, embedded applications may not have an "operator" initiating the program to supply the parameters, in which case it would be more appropriate for the program to have been compiled with a package containing the appropriate constant values or for the program to read the necessary values from switch settings or a downloaded auxiliary file. In any case, the variation in surrounding initiating environments is far too great to depend upon the kind of last-minute (program) parameterization implied by (subprogram) parameters to the main subprogram.

Language Ref Manual references: 6.1 Subprogram Declarations, 10.1 Compilation Units - Library Units


7.1.5 Encapsulating Implementation Dependencies

guideline

example

See Guideline 7.1.3.

rationale

Encapsulating hardware and implementation dependencies in a package allows the remainder of the code to ignore them and thus to be fully portable. It also localizes the dependencies, making it clear exactly which parts of the code may need to change when porting the program.

Some implementation-dependent features may be used to achieve particular performance or efficiency objectives. Commenting these objectives ensures that the programmer can find an appropriate way to achieve them when porting to a different implementation, or explicitly recognize that they cannot be achieved.

Interrupt entries are implementation-dependent features that may not be supported (e.g., VAX Ada uses pragmas to assign system traps to "normal" rendezvous). However, interrupt entries cannot be avoided in most embedded real-time systems and it is reasonable to assume that they are supported by an Ada implementation. The value for an interrupt is implementation-defined. Isolate it.

note

Ada can be used to write machine-dependent programs that take advantage of an implementation in a manner consistent with the Ada model, but which make particular choices where Ada allows implementation freedom. These machine dependencies should be treated in the same way as any other implementation dependent features of the code.

Language Ref Manual references: 2.7 Comments, 7.1 Package Structure, 7.2 Package Specifications and Declarations, 13.8 Machine Code Insertions, 13.9 Interface to Other Languages, F Implementation-Dependent Characteristics


7.1.6 Implementation-Added Features

guideline

rationale

Vendor-added features are not likely to be provided by other implementations. Even if a majority of vendors eventually provide similar additional features, they are unlikely to have identical formulations. Indeed, different vendors may use the same formulation for (semantically) entirely different features.

exceptions

There are many types of applications that require the use of these features. Examples include: multilingual systems that standardize on a vendor's file system, applications that are closely integrated with vendor products (i.e., user interfaces), and embedded systems for performance reasons. Isolate the use of these features into packages.

Language Ref Manual references: C Predefined Language Environment, F Implementation-Dependent Characteristics


Back to document index