M.3 Implementation Advice
This Reference 
Manual sometimes gives advice about handling certain target machine dependences. 
Each Ada implementation is required to document whether that advice is 
followed: 
Program_Error should be raised when an unsupported 
Specialized Needs Annex feature is used at run time. See 
1.1.3(20).
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).
If a bounded error or erroneous execution is detected, 
Program_Error should be raised. See 
1.1.5(12).
Implementation-defined pragmas should have no semantic 
effect for error-free programs. See 
2.8(16/3).
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).
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).
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).
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).
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).
Multidimensional arrays should be represented in 
row-major order, unless the array has convention Fortran. See 
3.6.2(11/3).
Tags.Internal_Tag should return the tag of a type, 
if one exists, whose innermost master is a master of the point of the 
function call. See 
3.9(26.1/3).
A real static expression with a nonformal 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).
For each language-defined private type T, T'Image 
should generate an image that would be meaningful based only on the relevant 
public interfaces. See 
4.10(56).
The value of Duration'Small should be no greater 
than 100 microseconds. See 
9.6(30).
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).
This paragraph 
was deleted.
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).
Exception_Information should provide information 
useful for debugging, and should include the Exception_Name and Exception_Message. 
See 
11.4.1(19).
Exception_Message by default should be short, provide 
information useful for debugging, and should not include the Exception_Name. 
See 
11.4.1(19).
Code executed for checks that have been suppressed 
should be minimized. See 
11.5(28).
The recommended level of support for all representation 
items should be followed. See 
13.1(28/5).
Storage allocated to objects of a packed type should 
be minimized. See 
13.2(6).
The recommended level of support for the Pack aspect 
should be followed. See 
13.2(9).
For an array X, X'Address should point at the first 
component of the array rather than the array bounds. See 
13.3(14).
The recommended level of support for the Address 
attribute should be followed. See 
13.3(19).
For any tagged specific subtype 
S, 
S'Class'Alignment 
should equal 
S'Alignment. See 
13.3(28).
The recommended level of support for the Alignment 
attribute should be followed. See 
13.3(35).
The Size of an array object should not include 
its bounds. See 
13.3(41.1/2).
If the Size of a subtype is nonconfirming and allows 
for efficient independent addressability, then the Object_Size of the 
subtype (unless otherwise specified) should equal the Size of the subtype. 
See 
13.3(52).
A Size clause on a composite subtype should not 
affect the internal layout of components. See 
13.3(53).
The recommended level of support for the Size attribute 
should be followed. See 
13.3(56).
An Object_Size clause on a composite type should 
not affect the internal layout of components. See 
13.3(58).
If S is a definite first subtype for which Object_Size 
is not specified, S'Object_Size should be the smallest multiple of the 
storage element size larger than or equal to S'Size that is consistent 
with the alignment of S. See 
13.3(58).
The recommended level of support for the Object_Size 
attribute should be followed. See 
13.3(58).
The Size of most objects of a subtype should equal 
the Object_Size of the subtype. See 
13.3(58).
The recommended level of support for the Component_Size 
attribute should be followed. See 
13.3(73).
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).
The recommended level of support for the nondefault 
bit ordering should be followed. See 
13.5.3(8).
Type System.Address should be a private type. See 
13.7(37).
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).
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).
There should not be unnecessary runtime 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).
The recommended level of support for Unchecked_Conversion 
should be followed. See 
13.9(17).
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).
A default storage pool for an access-to-constant 
type should not have overhead to support deallocation of individual objects. 
See 
13.11(24).
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 may have no mechanism for the deallocation 
of individual objects. See 
13.11(25).
For a standard storage pool, an instance of Unchecked_Deallocation 
should actually reclaim the storage. See 
13.11.2(17).
A call on an instance of Unchecked_Deallocation 
with a nonnull access value should raise Program_Error if the actual 
access type of the instance is a type for which the Storage_Size has 
been specified to be zero or is defined by the language to be zero. See 
13.11.2(17.1/3).
Streams.Storage.Bounded.Stream_Type objects should 
be implemented without implicit pointers or dynamic allocation. See 
13.13.1(37).
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).
The recommended level of support for the Stream_Size 
attribute should be followed. See 
13.13.2(1.8/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).
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/3).
The string returned by Wide_Characters.Handling.Character_Set_Version 
should include either “10646:” or “Unicode”. 
See 
A.3.5(62).
Bounded string objects should not be implemented 
by implicit pointers and dynamic allocation. See 
A.4.4(106).
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).
If an implementation supports other string encoding 
schemes, a child of Ada.Strings similar to UTF_Encoding should be defined. 
See 
A.4.11(107/3).
Bounded buffer objects should be implemented without 
dynamic allocation. See 
A.4.12(36).
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).
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).
Get_Immediate should be implemented with unbuffered 
input; input should be available immediately; line-editing should be 
disabled. See 
A.10.7(23).
Package Directories.Information should be provided 
to retrieve other information about a file. See 
A.16(124/2).
Directories.Start_Search and Directories.Search 
should raise Name_Error for malformed patterns. See 
A.16(125).
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).
Directories.Hierarchical_File_Names should be provided 
for systems with hierarchical file naming, and should not be provided 
on other systems. See 
A.16.1(36/3).
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).
Changes to the environment variables made outside 
the control of Environment_Variables should be reflected immediately. 
See 
A.17(33/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).
The worst-case time complexity of Element for Containers.Vector 
should be 
O(log 
N). See 
A.18.2(256/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/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).
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).
Containers.Vectors.Generic_Sorting.Sort and Containers.Vectors.Generic_Sorting.Merge 
should minimize copying of elements. See 
A.18.2(260/2).
Containers.Vectors.Move should not copy elements, 
and should minimize copying of internal data structures. See 
A.18.2(261/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).
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).
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).
Containers.Doubly_Linked_Lists.Move should not 
copy elements, and should minimize copying of internal data structures. 
See 
A.18.3(162/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).
Move for a map should not copy elements, and should 
minimize copying of internal data structures. See 
A.18.4(83/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).
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). The average time 
complexity of Containers.Hashed_Maps.Reserve_Capacity should be 
O(
N). 
See 
A.18.5(62/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).
Move for sets should not copy elements, and should 
minimize copying of internal data structures. See 
A.18.7(104/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).
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).
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).
The worst-case time complexity of the Element, 
Parent, First_Child, Last_Child, Next_Sibling, Previous_Sibling, Insert_Child 
with Count=1, and Delete operations of Containers.Multiway_Trees should 
be 
O(log 
N). See 
A.18.10(231/3).
Containers.Multiway_Trees.Move should not copy 
elements, and should minimize copying of internal data structures. See 
A.18.10(232/3).
If an exception is propagated from a tree operation, 
no storage should be lost, nor any elements removed from a tree unless 
specified by the operation. See 
A.18.10(233/3).
Move and Swap in Containers.Indefinite_Holders 
should not copy any elements, and should minimize copying of internal 
data structures. See 
A.18.18(73/5).
If an exception is propagated from a holder operation, 
no storage should be lost, nor should the element be removed from a holder 
container unless specified by the operation. See 
A.18.18(74/3).
Bounded vector objects should be implemented without 
implicit pointers or dynamic allocation. See 
A.18.19(16/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded vectors. See 
A.18.19(17/3).
Bounded list objects should be implemented without 
implicit pointers or dynamic allocation. See 
A.18.20(19/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded lists. See 
A.18.20(20/3).
Bounded hashed map objects should be implemented 
without implicit pointers or dynamic allocation. See 
A.18.21(21/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded hashed maps. See 
A.18.21(22/3).
Bounded ordered map objects should be implemented 
without implicit pointers or dynamic allocation. See 
A.18.22(18/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded ordered maps. See 
A.18.22(19/3).
Bounded hashed set objects should be implemented 
without implicit pointers or dynamic allocation. See 
A.18.23(20/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded hashed sets. See 
A.18.23(21/3).
Bounded ordered set objects should be implemented 
without implicit pointers or dynamic allocation. See 
A.18.24(17/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded ordered sets. See 
A.18.24(18/3).
Bounded tree objects should be implemented without 
implicit pointers or dynamic allocation. See 
A.18.25(19/3).
The implementation advice for procedure Move to 
minimize copying does not apply to bounded trees. See 
A.18.25(20/3).
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.26(10/2).
Containers.Generic_Array_Sort and Containers.Generic_Constrained_Array_Sort 
should minimize copying of elements. See 
A.18.26(11/2).
Containers.Generic_Sort should have an average 
time complexity better than 
O(
N**2) and worst case no worse 
than 
O(
N**2). See 
A.18.26(12/3).
Containers.Generic_Sort should minimize calls to 
the generic formal Swap. See 
A.18.26(13/3).
Bounded queue objects should be implemented without 
implicit pointers or dynamic allocation. See 
A.18.29(13/3).
Bounded priority queue objects should be implemented 
without implicit pointers or dynamic allocation. See 
A.18.31(14/3).
Bounded holder objects should be implemented without 
dynamic allocation. See 
A.18.32(15/5).
If 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/3).
Automatic elaboration of preelaborated packages 
should be provided when specifying the Export aspect as True is supported. 
See 
B.1(40/3).
For each supported convention 
L other than 
Intrinsic, specifying the aspects Import and Export should be supported 
for objects of 
L-compatible types and for subprograms, and aspect 
Convention should be supported for 
L-eligible types and for subprograms. 
See 
B.1(41/5).
The constants nul, wide_nul, char16_nul, and char32_nul 
in package Interfaces.C should have a representation of zero. See 
B.3(62.5/3).
If C interfacing is supported, the interface correspondences 
between Ada and C should be supported. See 
B.3(71).
If the C implementation supports unsigned long 
long and long long, unsigned_long_long and long_long should be supported. 
See 
B.3(71).
If COBOL interfacing is supported, the interface 
correspondences between Ada and COBOL should be supported. See 
B.4(98).
If Fortran interfacing is supported, the interface 
correspondences between Ada and Fortran should be supported. See 
B.5(26).
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).
Interface to assembler should be supported; the 
default assembler should be associated with the convention identifier 
Assembler. See 
C.1(4/3).
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 can read or update 
every object that is specified as exported. See 
C.1(5).
Little or no overhead should be associated with 
calling intrinsic and machine-code subprograms. See 
C.1(10).
Intrinsic subprograms should be provided to access 
any machine operations that provide special capabilities or efficiency 
not normally available. See 
C.1(16).
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).
Interrupt handlers should be called directly by 
the hardware. See 
C.3.1(20).
Violations of any implementation-defined restrictions 
on interrupt handlers should be detected before run time. See 
C.3.1(21).
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).
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).
If aspect Discard_Names is True for an entity, 
then the amount of storage used for storing names associated with that 
entity should be reduced. See 
C.5(8/4).
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/5).
A load or store of an atomic object should be implemented 
by a single load or store instruction. See 
C.6(23/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).
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).
Names that end with “_Locking” should 
be used for implementation-defined locking policies. See 
D.3(17).
Names that end with “_Queuing” should 
be used for implementation-defined queuing policies. See 
D.4(16).
The 
abort_statement 
should not require the task executing the statement to block. See 
D.6(9).
On a multi-processor, the delay associated with 
aborting a task on another processor should be bounded. See 
D.6(10).
When feasible, specified restrictions should be 
used to produce a more efficient implementation. See 
D.7(21).
When appropriate, mechanisms to change the value 
of Tick should be provided. See 
D.8(47).
Calendar.Clock and Real_Time.Clock should be transformations 
of the same time base. See 
D.8(48).
The “best” time base which exists in 
the underlying system should be available to the application through 
Real_Time.Clock. See 
D.8(49).
On a multiprocessor system, each processor should 
have a separate and disjoint ready queue. See 
D.13(9).
When appropriate, implementations should provide 
configuration mechanisms to change the value of Execution_Time.CPU_Tick. 
See 
D.14(29/2).
For a timing event, the handler should be executed 
directly by the real-time clock interrupt mechanism. See 
D.15(25).
Starting a protected action on a protected object 
statically assigned to a processor should not use busy-waiting. See 
D.16(16).
Each dispatching domain should have separate and 
disjoint ready queues. See 
D.16.1(31).
The PCS should allow for multiple tasks to call 
the RPC-receiver. See 
E.5(28).
The System.RPC.Write operation should raise Storage_Error 
if it runs out of space when writing an item. See 
E.5(29).
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/3).
Packed decimal should be used as the internal representation 
for objects of subtype 
S when 
S'Machine_Radix = 10. See 
F.1(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/3).
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/5).
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).
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).
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).
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).
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/3).
The equality operator should be used to test that 
a matrix in Numerics.Generic_Real_Arrays is symmetric. See 
G.3.1(90/2).
An implementation should minimize the circumstances 
under which the algorithm used for Numerics.Generic_Real_Arrays.Eigenvalues 
and Numerics.Generic_Real_Arrays.Eigensystem fails to converge. See 
G.3.1(91/3).
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/3).
The equality and negation operators should be used 
to test that a matrix is Hermitian. See 
G.3.2(160/2).
An implementation should minimize the circumstances 
under which the algorithm used for Numerics.Generic_Complex_Arrays.Eigenvalues 
and Numerics.Generic_Complex_Arrays.Eigensystem fails to converge. See 
G.3.2(160.1/3).
Mixed real and complex operations should not be 
performed by converting the real operand to complex. See 
G.3.2(161/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).
Object code listings should be provided both in 
a symbolic format and in a numeric format. See 
H.3.1(20).
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/3).
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 
J.15(9/5).
 Ada 2005 and 2012 Editions sponsored in part by Ada-Europe
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe