HP OpenVMS Systems

Content starts here

DEC Ada
Technical Overview and Comparison on DIGITAL Platforms


Previous Contents Index

2.4 Array Types

In DEC Ada, an object of an array type is stored as a vector of equally spaced storage cells, one cell for each component. Any space between the components is assumed to belong to the array object, and the space may or may not be read or written by operations on the object. The storage size for an object of an array type is determined by the following equation:


number of components * (component size + distance between components)

Multidimensional arrays are stored in row-major order. The default alignment of DEC Ada array components is as follows:

  • On OpenVMS VAX systems, array components are byte-aligned by default.
  • On OpenVMS Alpha and DIGITAL UNIX systems, array components are naturally aligned by default.

The pragma COMPONENT_ALIGNMENT can be used to change the default alignment for any array type. For more information, see Section 2.10.

A separate descriptor is used for passing arrays when necessary; for example, when the bounds of an array are not determined until execution of the program.

2.5 Record Types

In DEC Ada, the representation chosen for objects of a record type depends on a complex interaction between any applicable representation clauses or pragmas and the types or subtypes of the record components. DEC Ada does not place any implementation-defined components within the object.

Record representation clauses are supported. DEC Ada allows the simple expression in an alignment clause to have a value of 2n where:

  • On OpenVMS VAX systems, 0 <= n <= 9
  • On OpenVMS Alpha and DIGITAL UNIX systems, 0 <= n <= 16
  • On ULTRIX systems, 0 <= n <= 3

In other words, the simple expression must be an integer in the range 1 .. 512 on OpenVMS VAX or 1 .. 65536 that is also a power of 2 on OpenVMS Alpha and DIGITAL UNIX. The allocations then occur at addresses that are a multiple of the simple expression (a value of 2 aligns the data on a 2-byte boundary, a value of 4 aligns the data on a 4-byte boundary, and so on).

In the absence of a record representation clause, record components and subcomponents are aligned by default as follows:

  • On OpenVMS VAX systems, record components are byte-aligned by default.
  • On OpenVMS Alpha and DIGITAL UNIX systems, record components are naturally aligned by default.

The pragma COMPONENT_ALIGNMENT can be used to change the default alignment. For more information, see Section 2.10.

Storage allocation for records consists of the sum of the individual component allocations.

For a constrained object of a record type with discriminants, the allocation is that required for the given variant only. For an unconstrained object of a type with discriminants with defaults, the maximum size of each variant is used. Each object is contiguous and heap allocation is never used (even for dynamically sized components).

When the designated type is an unconstrained array type, the pointer contains the address of a descriptor that, in turn, includes index bounds and a pointer to the array object.

2.6 Access Types

DEC Ada uses a virtual address to represent the value of an access type. Storage allocation for an access type is a pointer that contains the address of the designated object. The size of the pointer depends on the underlying hardware and/or operating system. DEC Ada pointers are represented as follows:

  • On OpenVMS and ULTRIX systems, access types are represented in 32 bits (4 bytes).
  • On DIGITAL UNIX systems, access types are represented in 64 bits (8 bytes).

If the designated type has alignment greater than 512, the access type is unsupported.

In DEC Ada, storage is reclaimed only upon leaving the innermost block statement, subprogram body, or task body that encloses the access type declaration. In other words, storage for an inaccessible object of an access type is not reclaimed until the collection allocated for the access type is reclaimed or until the object is deallocated with UNCHECKED_DEALLOCATION.

DEC Ada does not provide automatic garbage collection. For more information, see Section 2.12.

2.7 Address Types

The language-defined type ADDRESS is implemented in the DEC Ada compiler as a private type for which conventional addition, subtraction, and relational operations are provided.

DEC Ada uses a virtual address to represent the value of an object of the type SYSTEM.ADDRESS. The storage size for an object of an address type is as follows:

  • On OpenVMS VAX, OpenVMS Alpha, and ULTRIX systems, storage size is 32 bits (4 bytes).
  • On DIGITAL UNIX systems, storage size is 64 bits (8 bytes).

The implementation-defined generic subprograms FETCH_FROM_ADDRESS and ASSIGN_TO_ADDRESS provide the ability to read from or write to memory at an arbitrary address according to the instantiated type.

The function TO_ADDRESS allows the conversion of universal integers to the type ADDRESS. However, addresses on DIGITAL UNIX systems are 64-bit and UNSIGNED_LONGWORD is 32-bits. Therefore, DIGITAL recommends using the generic package ADDRESS_OPERATIONS.

In addition to the address-related types and operations in the package SYSTEM, DEC Ada provides the package ADDRESS_OPERATIONS. This package provides generic address and integer operations to allow conversions across 32- and 64-bit systems.

2.8 STARLET Bindings Restriction

The STARLET bindings for OpenVMS VAX and for OpenVMS Alpha are different because of the differences between the two systems. There are bindings for Alpha that do not exist for VAX, because OpenVMS has different system routines on the two systems.

A particular incompatibility between STARLET bindings on OpenVMS VAX and OpenVMS Alpha is that some types (for example, ATR_TYPE, component ADDR) were updated from UNSIGNED_LONGWORD to ADDRESS in DEC Ada V3.2 for OpenVMS Alpha, but left as UNSIGNED_LONGWORD on VAX.

To avoid a problem, you can edit your copy of the STARLET bindings to use your preferred type, and then recompile them into the Ada Predefined Library. For example:


$ ACS SET LIBRARY ADA$PREDEFINED:
$ ACS EXTRACT SOURCE STARLET
$ EDIT STARLET_.ADA
...   ! Change types as needed
$ ADA /NODEBUG/NOSMART/NONOTE STARLET_.ADA

2.9 Task Types

When an object of a task type is declared, the value of the object is used by the DEC Ada Run-Time Library to determine the address of the task control block created for the task.

The storage size for an object of a task type is as follows:

  • On OpenVMS VAX systems, storage size is 4 bytes (32 bits).
  • On OpenVMS Alpha systems, storage size is 8 bytes (64 bits).
  • On DIGITAL UNIX systems, storage size is 16 bytes (128 bits).

See Chapter 4 for more information about tasks and task-related features of DEC Ada.

2.10 Component Alignment

The DEC Ada compiler distinguishes between types that are able to be aligned by bit and those that are able to be aligned by byte. Components of types that can be aligned by bit can be allocated beginning at arbitrary bit offsets in component clauses, while components of types that can be aligned by byte must be allocated at byte (addressable storage) boundaries. In general, the following types are bit-alignable:

  • Discrete types
  • Arrays of discrete types
  • Record types with a system-limited size (32 or 64 bits)

Other types cannot be aligned by bit.

In DEC Ada, each noncomposite component (scalar, access, and so on) is aligned by default on an appropriate boundary, according to the following conventions:

  • On OpenVMS VAX systems, all noncomposite components are aligned on byte boundaries.
  • On OpenVMS Alpha, DIGITAL UNIX, and ULTRIX systems, all noncomposite components are aligned on natural boundaries. For example, 1-byte components are aligned on byte boundaries, 2-byte components on 2-byte boundaries, 4-byte components on 4-byte boundaries, and so on.
    The OpenVMS Alpha and DIGITAL UNIX hardware runs more efficiently with naturally aligned data.

Although the VAX hardware generally requires little alignment, alignment clauses can be useful in a mixed-language environment when you want to force objects to particular boundaries or for data compatibility between machine architectures.

Pragma COMPONENT_ALIGNMENT

The DEC Ada compiler provides the representation pragma COMPONENT_ALIGNMENT, which allows control over the alignment of array and record components. The alignment choices are briefly defined as follows:

  • COMPONENT_SIZE
    Produces natural alignment. Components are aligned on boundaries appropriate for their size. Explicit specification of the COMPONENT_SIZE choice ensures that natural alignment is used across all OpenVMS VAX, OpenVMS Alpha, and DIGITAL UNIX systems. COMPONENT_SIZE is the default choice on OpenVMS Alpha and DIGITAL UNIX systems.
  • COMPONENT_SIZE_4
    Produces natural alignment for components with a size of 4 or fewer bytes. Anything larger is aligned on 4-byte boundaries.
  • DEFAULT
    Produces byte alignment on VAX systems. On all other systems, DEFAULT produces natural alignment.
  • STORAGE_UNIT
    Produces byte alignment. STORAGE_UNIT is the default choice on VAX systems.

If a pragma COMPONENT_ALIGNMENT does not apply to a type, then a default alignment is used. On VAX systems, the default alignment is byte alignment. On OpenVMS Alpha and DIGITAL UNIX systems, the default is natural alignment.

2.11 Representation Clauses

Representation clauses specify how the types of the language are to be mapped onto the underlying hardware. DEC Ada provides several mechanisms to enable the control of representations of new or derived types.

Representation clauses provide a high level of control over particular layouts and data alignments. Specific representation clauses are as follows:

  • Length representation clauses provide explicit control over the amount of storage allocated for objects of a particular type.
  • Enumeration representation clauses specify the internal codes that represent the literals of an enumeration type.
  • Record representation clauses force a record type to have a particular representation. These clauses are useful when it is necessary to lay out an area of memory in a particular way.
  • Alignment clauses. When a record representation clause is used to define the layout of a record type, the option exists for specifying an alignment clause to determine the alignment of all record objects of that type.
    In DEC Ada, records can be aligned on any byte address that is a power of 2 up to 512 (or 29).

These clauses override the pragmas PACK and COMPONENT_ALIGNMENT.

DEC Ada does not allow a representation clause for a type that depends on a generic formal type.

2.11.1 Length Clauses

In DEC Ada, for a discrete type, the given size must not exceed the maximum size (in bits) for the given type. On OpenVMS VAX systems, the maximum size is 32 for all types. On OpenVMS Alpha and DIGITAL UNIX systems, the maximum size is 64 for integer and enumeration types and 32 for fixed-point types. The given size becomes the default allocation for all objects and components (in arrays and records) of that type.

For integer and enumeration types, the given size affects the internal representation as follows: for integer types, high order bits are sign-extended; for enumeration types, the high order bits can be either zero- or sign-extended depending upon the base representation that is selected.

For fixed-point types, the given size affects the range (but not the precision) of the underlying model numbers of the type.

For all other types, the given size must equal the size that would apply in the absence of a size specification.

2.11.2 Address Clauses

In DEC Ada, address clauses are used to store objects (constants and variables) or imported subprograms at specific memory locations. Address clauses can be used to precisely map and overlay memory areas during program execution.

When specifying an address clause, the simple name of an entity must be the name of an object or imported subprogram. On DIGITAL UNIX systems, the simple name can also be the name of a single entry.

On OpenVMS systems, DEC Ada provides the pragma AST_ENTRY and the AST_ENTRY attribute as alternative mechanisms for handling asynchronous interrupts from the OpenVMS operating system.

On DIGITAL UNIX systems, entries for address representation clauses are supported to allow some DIGITAL UNIX signals to be associated with task entry calls.

In DEC Ada, a representation clause is not allowed for:

  • Generic formal types
  • Types that depends on a generic formal type
  • Composite types that have a component or subcomponent of a generic formal type
  • Types derived from a generic formal type

2.11.3 Storage Representation Pragmas

DEC Ada provides the representation pragma COMPONENT_ALIGNMENT to allow the specification of a default storage representation for declarative parts or array or record types. For more information, see Section 2.10.

The predefined pragma PACK minimizes gaps between the components of composite types (record and array types). Pragma PACK has an effect on the record or array components that can be packed and it can also have an effect on component alignment.

When the pragma PACK and the pragma COMPONENT_ALIGNMENT are applied to the same type, the pragma PACK takes precedence over the pragma COMPONENT_ALIGNMENT.

DEC Ada provides the pragma TASK_STORAGE to allow the specification of additional storage, called the guard area, for each task activation.

DEC Ada provides the pragma MAIN_STORAGE to allow a fixed-size stack and stack storage areas to be specified for the task associated with a main program. Working storage can also be specified for the task activation, and additional storage, or guard pages, can be specified to provide protection against storage overflow during task execution of non-Ada code.

2.12 Storage Allocation and Deallocation

The DEC Ada compiler stores objects in registers, on a stack, in static memory, or in dynamic memory (on the heap) depending on the objects' sizes (when their sizes are known), their types, the length of their lifetimes, and their uses.

DEC Ada does not provide garbage collection. However, there are at least two ways to deallocate objects of access types:

  • Use the fact that the collection associated with an access type is automatically deallocated when the end statement of the scope containing the access type is encountered.
  • Instantiate the language-defined generic procedure UNCHECKED_DEALLOCATION and call the instantiation to explicitly deallocate the storage for an object designated by a value of an access type.


Chapter 3
Pragmas

This chapter is divided into the following sections:

  • Language-defined pragmas
  • Implementation-defined pragmas
  • Pragmas supplied on other platforms

For more information on these pragmas, see the DEC Ada Language Reference Manual.

3.1 Language-Defined Pragmas

Table 3-1 lists the language-defined pragmas supported by the DEC Ada compiler.

Table 3-1 Language-Defined Pragmas
Pragma Comments
CONTROLLED  
ELABORATE  
INLINE In DEC Ada, a call of a subprogram for which the pragma INLINE has been specified is expanded inline providing that certain conditions are satisfied. For details of these conditions and further restrictions, see the DEC Ada Language Reference Manual.
INTERFACE The pragma INTERFACE recognizes the following language names (keynames given):
  • On OpenVMS systems: ADA, BLISS, C, FORTRAN, and DEFAULT (default)
  • On DIGITAL UNIX and ULTRIX systems: ADA, BLISS, C (default), and FORTRAN

In DEC Ada, the use of this pragma is restricted. When the pragma INTERFACE applies to more than one subprogram, it must be supplemented by one of the following implementation-defined pragmas (which identify the distinct foreign routines corresponding to each internal subprogram declaration):

  • IMPORT_FUNCTION
  • IMPORT_PROCEDURE
  • IMPORT_VALUED_PROCEDURE
  • INTERFACE_NAME

The pragma INTERFACE is not needed for exporting subprograms.

LIST  
MEMORY_SIZE  
OPTIMIZE In DEC Ada, the pragma OPTIMIZE is allowed only immediately within a declarative part of a body declaration.
PACK  
PAGE  
PRIORITY  
SHARED  
STORAGE_UNIT In DEC Ada, the only argument allowed for this pragma is 8 (bits).
SUPPRESS  
SYSTEM_NAME The pragma SYSTEM_NAME is allowed only at the start of a compilation, before the first compilation unit, if any, of the compilation. The pragma takes an enumeration literal as its single argument. The effect of the pragma is to use the enumeration literal with the specified identifier for the definition of the constant SYSTEM_NAME. This pragma is allowed only if the specified identifier corresponds to one of the literals of the type NAME.

In DEC Ada, the enumeration literals for the type NAME are system-specific, as follows:

  • VAX_VMS (on OpenVMS VAX)
  • OpenVMS_AXP (on OpenVMS Alpha)
  • DEC_OSF1_AXP (on DIGITAL UNIX)

3.2 Implementation-Defined Pragmas

DIGITAL supports a similar set of pragmas on all DIGITAL platforms. The implementation-defined pragmas are listed in Table 3-2, which also contains comments on differences where they do exist.

Table 3-2 DEC Ada Implementation-Defined Pragmas
Pragma Platform and Comments
AST_ENTRY OpenVMS
COMMON_OBJECT All
  The pragmas COMMON_OBJECT and PSECT_OBJECT allow an Ada variable to be associated with a common storage area and, therefore, made to correspond to a Fortran common block.
COMPONENT_ALIGNMENT All
  For more information, see Section 2.10.
EXPORT_EXCEPTION OpenVMS
  This pragma allows an Ada exception to be exported as a condition value. This pragma is the converse of IMPORT_EXCEPTION.
EXPORT_FUNCTION All
  This pragma allows DEC Ada subprograms to be called by other DIGITAL languages. It is the converse of IMPORT_FUNCTION.
EXPORT_OBJECT All
  This pragma is generally restricted to use with variables declared in library packages (such variables are statically allocated).
EXPORT_PROCEDURE All
  This pragma is the converse of IMPORT_PROCEDURE.
EXPORT_VALUED_PROCEDURE All
  When a main function or a main procedure declared with the pragma EXPORT_VALUED_PROCEDURE returns a discrete value whose size is less than 32 bits (on OpenVMS VAX systems) or 64 bits (on OpenVMS Alpha and DIGITAL UNIX systems), the value is zero- or sign-extended, as appropriate.

This pragma permits an Ada procedure to behave as a function that both returns a value and causes side effects on its parameters when it is called from a routine written in another programming language.

This pragma is the converse of IMPORT_VALUED_PROCEDURE.

FLOAT_REPRESENTATION OpenVMS, DIGITAL UNIX
  For more information, see Section 2.2.1.
IDENT All
IMPORT_EXCEPTION OpenVMS
  This pragma is the converse of EXPORT_EXCEPTION.
IMPORT_FUNCTION All
  This pragma can be used to specify the parameter-passing mechanism to be used (by value, by reference, or by descriptor) when the mechanisms required by the external routine differ from the default mechanisms that would be used by the DEC Ada compiler.
IMPORT_OBJECT All
IMPORT_PROCEDURE All
  This pragma can be used to specify the parameter-passing mechanism to be used (by value, by reference, or by descriptor) when the mechanisms required by the external routine differ from the default mechanisms that would be used by the DEC Ada compiler.

On OpenVMS systems, the first optional parameter is also available as an argument.

IMPORT_VALUED_PROCEDURE All
  This pragma can be used to specify the parameter-passing mechanism to be used (by value, by reference, or by descriptor) when the mechanisms required by the external routine differ from the default mechanisms that would be used by the DEC Ada compiler.

On OpenVMS systems, the first optional parameter is also available as an argument.

This pragma also allows "functions" in the environment that also update their parameters to be declared and called as procedures. (Functions in the Ada language are not allowed to have in out or out parameters.)

INLINE_GENERIC All
INTERFACE_NAME All
LONG_FLOAT OpenVMS
  For more information, see Section 2.2.2.
MAIN_STORAGE OpenVMS VAX
  For more information, see Section 4.2.4.
PASSIVE OpenVMS Alpha, DIGITAL UNIX
  For more information, see Section 4.6.1.
PSECT_OBJECT OpenVMS
  The pragmas PSECT_OBJECT and COMMON_OBJECT allow an Ada variable to be associated with a common storage area and, therefore, made to correspond to a Fortran common block.
SHARE_GENERIC OpenVMS VAX
SUPPRESS_ALL All
TASK_STORAGE All
  For more information, see Section 4.2.4.
TIME_SLICE OpenVMS, DIGITAL UNIX
  Implementation differences across systems.

For more information, see Section 4.3.2.

TITLE All
VOLATILE All

3.3 Pragmas Supplied on Other Ada Implementations

The Rational Corporation VADS compiler supplies all language-defined pragmas as specified by the Ada 83 standard (and more). For information on the differences between pragmas supplied by VADS and pragmas supplied by DEC Ada, see Section C.8. These differences can affect applications being ported between VADS and DEC Ada.

The Ada Core Technology GNAT compiler (Ada 95) supplies all language-defined pragmas as specified by the Ada 83 standard. For information on the GNAT-supplied DIGITAL implementation-defined pragmas and GNAT-supplied Ada 95 pragmas, see Appendix E.


Previous Next Contents Index