Implementation Advice
Author: JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor

Ada Reference Manual — Legal Information

# M.3 Implementation Advice

1/2
This International Standard sometimes gives advice about handling certain target machine dependences. Each Ada implementation must document whether that advice is followed:
2/2

- Program_Error should be raised when an unsupported Specialized Needs Annex feature is used at run time. See 1.1.3(20).

3/2

- Implementation-defined extensions to the functionality of a language-defined library unit should be provided by adding children to the library unit. See 1.1.3(21).

4/2

- If a bounded error or erroneous execution is detected, Program_Error should be raised. See 1.1.5(12).

5/2

- Implementation-defined pragmas should have no semantic effect for error-free programs. See 2.8(16).

6/2

- Implementation-defined pragmas should not make an illegal program legal, unless they complete a declaration or configure the library_items in an environment. See 2.8(19).

7/2

- Long_Integer should be declared in Standard if the target supports 32-bit arithmetic. No other named integer subtypes should be declared in Standard. See 3.5.4(28).

8/2

- For a two's complement target, modular types with a binary modulus up to System.Max_Int*2+2 should be supported. A nonbinary modulus up to Integer'Last should be supported. See 3.5.4(29).

9/2

- Program_Error should be raised for the evaluation of S'Pos for an enumeration type, if the value of the operand does not correspond to the internal code for any enumeration literal of the type. See 3.5.5(8).

10/2

- Long_Float should be declared in Standard if the target supports 11 or more digits of precision. No other named float subtypes should be declared in Standard. See 3.5.7(17).

11/2

- Multidimensional arrays should be represented in row-major order, unless the array has convention Fortran. See 3.6.2(11).

12/2

- Tags.Internal_Tag should return the tag of a type whose innermost master is the master of the point of the function call.. See 3.9(26.1/2).

13/2

- For a real static expression with a non-formal type that is not part of a larger static expression should be rounded the same as the target system. See 4.9(38.1/2).

14/2

- The value of Duration'Small should be no greater than 100 microseconds. See 9.6(30).

15/2

- The time base for delay_relative_statements should be monotonic. See 9.6(31).

16/2

- Leap seconds should be supported if the target system supports them. Otherwise, operations in Calendar.Formatting should return results consistent with no leap seconds. See 9.6.1(89/2).

17/2

- When applied to a generic unit, a program unit pragma that is not a library unit pragma should apply to each instance of the generic unit for which there is not an overriding pragma applied directly to the instance. See 10.1.5(10/1).

18/2

- A type declared in a preelaborated package should have the same representation in every elaboration of a given version of the package. See 10.2.1(12).

19/2

- Exception_Message by default should be short, provide information useful for debugging, and should not include the Exception_Name. See 11.4.1(19).

20/2

- Exception_Information should provide information useful for debugging, and should include the Exception_Name and Exception_Message. See 11.4.1(19).

21/2

- Code executed for checks that have been suppressed should be minimized. See 11.5(28).

22/2

- The recommended level of support for all representation items should be followed. See 13.1(28/2).

23/2

- Storage allocated to objects of a packed type should be minimized. See 13.2(6).

24/2

- The recommended level of support for pragma Pack should be followed. See 13.2(9).

25/2

- For an array X, X'Address should point at the first component of the array rather than the array bounds. See 13.3(14).

26/2

- The recommended level of support for the Address attribute should be followed. See 13.3(19).

27/2

- The recommended level of support for the Alignment attribute should be followed. See 13.3(35).

28/2

- The Size of an array object should not include its bounds. See 13.3(41.1/2).

29/2

- If the Size of a subtype allows for efficient independent addressability, then the Size of most objects of the subtype should equal the Size of the subtype. See 13.3(52).

30/2

- A Size clause on a composite subtype should not affect the internal layout of components. See 13.3(53).

31/2

- The recommended level of support for the Size attribute should be followed. See 13.3(56).

32/2

- The recommended level of support for the Component_Size attribute should be followed. See 13.3(73).

33/2

- The recommended level of support for enumeration_representation_clauses should be followed. See 13.4(10).

34/2

- The recommended level of support for record_representation_clauses should be followed. See 13.5.1(22).

35/2

- If a component is represented using a pointer to the actual data of the component which is contiguous with the rest of the object, then the storage place attributes should reflect the place of the actual data. If a component is allocated discontiguously from the rest of the object, then a warning should be generated upon reference to one of its storage place attributes. See 13.5.2(5).

36/2

- The recommended level of support for the nondefault bit ordering should be followed. See 13.5.3(8).

37/2

- Type System.Address should be a private type. See 13.7(37).

38/2

- Operations in System and its children should reflect the target environment; operations that do not make sense should raise Program_Error. See 13.7.1(16).

39/2

- Since the Size of an array object generally does not include its bounds, the bounds should not be part of the converted data in an instance of Unchecked_Conversion. See 13.9(14/2).

40/2

- There should not be unnecessary run-time checks on the result of an Unchecked_Conversion; the result should be returned by reference when possible. Restrictions on Unchecked_Conversions should be avoided. See 13.9(15).

41/2

- The recommended level of support for Unchecked_Conversion should be followed. See 13.9(17).

42/2

- Any cases in which heap storage is dynamically allocated other than as part of the evaluation of an allocator should be documented. See 13.11(23).

43/2

- A default storage pool for an access-to-constant type should not have overhead to support deallocation of individual objects. See 13.11(24).

44/2

- Usually, a storage pool for an access discriminant or access parameter should be created at the point of an allocator, and be reclaimed when the designated object becomes inaccessible. For other anonymous access types, the pool should be created at the point where the type is elaborated and need not support deallocation of individual objects. See 13.11(25).

45/2

- For a standard storage pool, an instance of Unchecked_Deallocation should actually reclaim the storage. See 13.11.2(17).

46/2

- The recommended level of support for the Stream_Size attribute should be followed. See 13.13.2(1.8/2).

47/2

- If not specified, the value of Stream_Size for an elementary type should be the number of bits that corresponds to the minimum number of stream elements required by the first subtype of the type, rounded up to the nearest factor or multiple of the word size that is also a multiple of the stream element size. See 13.13.2(1.6/2).

48/2

- If an implementation provides additional named predefined integer types, then the names should end with “Integer”. If an implementation provides additional named predefined floating point types, then the names should end with “Float”. See A.1(52).

49/2

- Implementation-defined operations on Wide_Character, Wide_String, Wide_Wide_Character, and Wide_Wide_String should be child units of Wide_Characters or Wide_Wide_Characters. See A.3.1(7/2).

50/2

- Bounded string objects should not be implemented by implicit pointers and dynamic allocation. See A.4.4(106).

51/2

- Strings.Hash should be good a hash function, returning a wide spread of values for different string values, and similar strings should rarely return the same value. See A.4.9(12/2).

52/2

- Any storage associated with an object of type Generator of the random number packages should be reclaimed on exit from the scope of the object. See A.5.2(46).

53/2

- Each value of Initiator passed to Reset for the random number packages should initiate a distinct sequence of random numbers, or, if that is not possible, be at least a rapidly varying function of the initiator value. See A.5.2(47).

54/2

- Get_Immediate should be implemented with unbuffered input; input should be available immediately; line-editing should be disabled. See A.10.7(23).

55/2

- Package Directories.Information should be provided to retrieve other information about a file. See A.16(124/2).

56/2

- Directories.Start_Search and Directories.Search should raise Use_Error for malformed patterns. See A.16(125/2).

57/2

- Directories.Rename should be supported at least when both New_Name and Old_Name are simple names and New_Name does not identify an existing external file. See A.16(126/2).

58/2

- If the execution environment supports subprocesses, the current environment variables should be used to initialize the environment variables of a subprocess. See A.17(32/2).

59/2

- Changes to the environment variables made outside the control of Environment_Variables should be reflected immediately. See A.17(33/2).

60/2

- Containers.Hash_Type'Modulus should be at least 2**32. Containers.Count_Type'Last should be at least 2**31–1. See A.18.1(8/2).

61/2

- The worst-case time complexity of Element for Containers.Vector should be O(log N). See A.18.2(256/2).

62/2

- The worst-case time complexity of Append with Count = 1 when N is less than the capacity for Containers.Vector should be O(log N). See A.18.2(257).

63/2

- The worst-case time complexity of Prepend with Count = 1 and Delete_First with Count=1 for Containers.Vectors should be O(N log N). See A.18.2(258/2).

64/2

- The worst-case time complexity of a call on procedure Sort of an instance of Containers.Vectors.Generic_Sorting should be O(N**2), and the average time complexity should be better than O(N**2). See A.18.2(259/2).

65/2

- Containers.Vectors.Generic_Sorting.Sort and Containers.Vectors.Generic_Sorting.Merge should minimize copying of elements. See A.18.2(260/2).

66/2

- Containers.Vectors.Move should not copy elements, and should minimize copying of internal data structures. See A.18.2(261/2).

67/2

- If an exception is propagated from a vector operation, no storage should be lost, nor any elements removed from a vector unless specified by the operation. See A.18.2(262/2).

68/2

- The worst-case time complexity of Element, Insert with Count=1, and Delete with Count=1 for Containers.Doubly_Linked_Lists should be O(log N). See A.18.3(160/2).

69/2

- a call on procedure Sort of an instance of Containers.Doubly_Linked_Lists.Generic_Sorting should have an average time complexity better than O(N**2) and worst case no worse than O(N**2). See A.18.3(161/2).

70/2

- Containers.Doubly_Link_Lists.Move should not copy elements, and should minimize copying of internal data structures. See A.18.3(162/2).

71/2

- If an exception is propagated from a list operation, no storage should be lost, nor any elements removed from a list unless specified by the operation. See A.18.3(163/2).

72/2

- Move for a map should not copy elements, and should minimize copying of internal data structures. See A.18.4(83/2).

73/2

- If an exception is propagated from a map operation, no storage should be lost, nor any elements removed from a map unless specified by the operation. See A.18.4(84/2).

74/2

- The average time complexity of Element, Insert, Include, Replace, Delete, Exclude and Find operations that take a key parameter for Containers.Hashed_Maps should be O(log N). The average time complexity of the subprograms of Containers.Hashed_Maps that take a cursor parameter should be O(1). See A.18.5(62/2).

75/2

- The worst-case time complexity of Element, Insert, Include, Replace, Delete, Exclude and Find operations that take a key parameter for Containers.Ordered_Maps should be O((log N)**2) or better. The worst-case time complexity of the subprograms of Containers.Ordered_Maps that take a cursor parameter should be O(1). See A.18.6(95/2).

76/2

- Move for sets should not copy elements, and should minimize copying of internal data structures. See A.18.7(104/2).

77/2

- If an exception is propagated from a set operation, no storage should be lost, nor any elements removed from a set unless specified by the operation. See A.18.7(105/2).

78/2

- The average time complexity of the Insert, Include, Replace, Delete, Exclude and Find operations of Containers.Hashed_Sets that take an element parameter should be O(log N). The average time complexity of the subprograms of Containers.Hashed_Sets that take a cursor parameter should be O(1). The average time complexity of Containers.Hashed_Sets.Reserve_Capacity should be O(N). See A.18.8(88/2).

79/2

- The worst-case time complexity of the Insert, Include, Replace, Delete, Exclude and Find operations of Containers.Ordered_Sets that take an element parameter should be O((log N)**2). The worst-case time complexity of the subprograms of Containers.Ordered_Sets that take a cursor parameter should be O(1). See A.18.9(116/2).

80/2

- Containers.Generic_Array_Sort and Containers.Generic_Constrained_Array_Sort should have an average time complexity better than O(N**2) and worst case no worse than O(N**2). See A.18.16(10/2).

81/2

- Containers.Generic_Array_Sort and Containers.Generic_Constrained_Array_Sort should minimize copying of elements. See A.18.16(11/2).

82/2

- If pragma Export is supported for a language, the main program should be able to be written in that language. Subprograms named "adainit" and "adafinal" should be provided for elaboration and finalization of the environment task. See B.1(39).

83/2

- Automatic elaboration of preelaborated packages should be provided when pragma Export is supported. See B.1(40).

84/2

- For each supported convention L other than Intrinsic, pragmas Import and Export should be supported for objects of L-compatible types and for subprograms, and pragma Convention should be supported for L-eligible types and for subprograms. See B.1(41).

85/2

- If an interface to C, COBOL, or Fortran is provided, the corresponding package or packages described in Annex B, “Interface to Other Languages” should also be provided. See B.2(13).

86/2

- The constants nul, wide_nul, char16_nul, and char32_nul in package Interfaces.C should have a representation of zero. See B.3(62.1/2).

87/2

- If C interfacing is supported, the interface correspondences between Ada and C should be supported. See B.3(71).

88/2

- If COBOL interfacing is supported, the interface correspondences between Ada and COBOL should be supported. See B.4(98).

89/2

- If Fortran interfacing is supported, the interface correspondences between Ada and Fortran should be supported. See B.5(26).

90/2

- The machine code or intrinsics support should allow access to all operations normally available to assembly language programmers for the target environment. See C.1(3).

91/2

- Interface to assembler should be supported; the default assembler should be associated with the convention identifier Assembler. See C.1(4).

92/2

- If an entity is exported to assembly language, then the implementation should allocate it at an addressable location even if not otherwise referenced from the Ada code. A call to a machine code or assembler subprogram should be treated as if it could read or update every object that is specified as exported. See C.1(5).

93/2

- Little or no overhead should be associated with calling intrinsic and machine-code subprograms. See C.1(10).

94/2

- Intrinsic subprograms should be provided to access any machine operations that provide special capabilities or efficiency not normally available. See C.1(16).

95/2

- If the Ceiling_Locking policy is not in effect and the target system allows for finer-grained control of interrupt blocking, a means for the application to specify which interrupts are to be blocked during protected actions should be provided. See C.3(28/2).

96/2

- Interrupt handlers should be called directly by the hardware. See C.3.1(20).

97/2

- Violations of any implementation-defined restrictions on interrupt handlers should be detected before run time. See C.3.1(21).

98/2

- If implementation-defined forms of interrupt handler procedures are supported, then for each such form of a handler, a type analogous to Parameterless_Handler should be specified in a child package of Interrupts, with the same operations as in the predefined package Interrupts. See C.3.2(25).

99/2

- Preelaborated packages should be implemented such that little or no code is executed at run time for the elaboration of entities. See C.4(14).

100/2

- If pragma Discard_Names applies to an entity, then the amount of storage used for storing names associated with that entity should be reduced. See C.5(8).

101/2

- A load or store of a volatile object whose size is a multiple of System.Storage_Unit and whose alignment is nonzero, should be implemented by accessing exactly the bits of the object and no others. See C.6(22/2).

102/2

- A load or store of an atomic object should be implemented by a single load or store instruction. See C.6(23/2).

103/2

- Finalization of task attributes and reclamation of associated storage should be performed as soon as possible after task termination. See C.7.2(30.1/2).

104/2

- If the target domain requires deterministic memory use at run time, storage for task attributes should be pre-allocated statically and the number of attributes pre-allocated should be documented. See C.7.2(30).

105/2

- Names that end with “_Locking” should be used for implementation-defined locking policies. See D.3(17).

106/2

- Names that end with “_Queuing” should be used for implementation-defined queuing policies. See D.4(16).

107/2

- The abort_statement should not require the task executing the statement to block. See D.6(9).

108/2

- On a multi-processor, the delay associated with aborting a task on another processor should be bounded. See D.6(10).

109/2

- When feasible, specified restrictions should be used to produce a more efficient implementation. See D.7(21).

110/2

- When appropriate, mechanisms to change the value of Tick should be provided. See D.8(47).

111/2

- Calendar.Clock and Real_Time.Clock should be transformations of the same time base. See D.8(48).

112/2

- The “best” time base which exists in the underlying system should be available to the application through Real_Time.Clock. See D.8(49).

113/2

- When appropriate, implementations should provide configuration mechanisms to change the value of Execution_Time.CPU_Tick. See D.14(29/2).

114/2

- For a timing event, the handler should be executed directly by the real-time clock interrupt mechanism. See D.15(25).

115/2

- The PCS should allow for multiple tasks to call the RPC-receiver. See E.5(28).

116/2

- The System.RPC.Write operation should raise Storage_Error if it runs out of space when writing an item. See E.5(29).

117/2

- If COBOL (respectively, C) is supported in the target environment, then interfacing to COBOL (respectively, C) should be supported as specified in Annex B. See F(7).

118/2

- Packed decimal should be used as the internal representation for objects of subtype S when S'Machine_Radix = 10. See F.1(2).

119/2

- If Fortran (respectively, C) is supported in the target environment, then interfacing to Fortran (respectively, C) should be supported as specified in Annex B. See G(7).

120/2

- Mixed real and complex operations (as well as pure-imaginary and complex operations) should not be performed by converting the real (resp. pure-imaginary) operand to complex. See G.1.1(56).

121/2

- If Real'Signed_Zeros is true for Numerics.Generic_Complex_Types, a rational treatment of the signs of zero results and result components should be provided. See G.1.1(58).

122/2

- If Complex_Types.Real'Signed_Zeros is true for Numerics.Generic_Complex_Elementary_Functions, a rational treatment of the signs of zero results and result components should be provided. See G.1.2(49).

123/2

- For elementary functions, the forward trigonometric functions without a Cycle parameter should not be implemented by calling the corresponding version with a Cycle parameter. Log without a Base parameter should not be implemented by calling Log with a Base parameter. See G.2.4(19).

124/2

- For complex arithmetic, the Compose_From_Polar function without a Cycle parameter should not be implemented by calling Compose_From_Polar with a Cycle parameter. See G.2.6(15).

125/2

- Solve and Inverse for Numerics.Generic_Real_Arrays should be implemented using established techniques such as LU decomposition and the result should be refined by an iteration on the residuals. See G.3.1(88/2).

126/2

- The equality operator should be used to test that a matrix in Numerics.Generic_Real_Matrix is symmetric. See G.3.1(90/2).

127/2

- Solve and Inverse for Numerics.Generic_Complex_Arrays should be implemented using established techniques and the result should be refined by an iteration on the residuals. See G.3.2(158/2).

128/2

- The equality and negation operators should be used to test that a matrix is Hermitian. See G.3.2(160/2).

129/2

- Mixed real and complex operations should not be performed by converting the real operand to complex. See G.3.2(161/2).

130/2

- The information produced by pragma Reviewable should be provided in both a human-readable and machine-readable form, and the latter form should be documented. See H.3.1(19).

131/2

- Object code listings should be provided both in a symbolic format and in a numeric format. See H.3.1(20).

132/2

- If the partition elaboration policy is Sequential and the Environment task becomes permanently blocked during elaboration then the partition should be immediately terminated. See H.6(15/2).

Sponsored by Ada-Europe