1.1.3 Conformity of an Implementation
Implementation Requirements
A
conforming implementation shall:
Discussion: The
implementation
is the software and hardware that implements the language. This includes
compiler, linker, operating system, hardware, etc.
We first define what it means to “conform”
in general — basically, the implementation has to properly implement
the normative rules given throughout the Reference Manual. Then we define
what it means to conform to a Specialized Needs Annex — the implementation
must support the core features plus the features of that Annex. Finally,
we define what it means to “conform to the Reference Manual”
— this requires support for the core language, and allows partial
(but not conflicting) support for the Specialized Needs Annexes.
Translate and correctly execute legal programs
written in Ada, provided that they are not so large as to exceed the
capacity of the implementation;
Identify all programs or program units that are
so large as to exceed the capacity of the implementation (or raise an
appropriate exception at run time);
Implementation defined: Capacity limitations
of the implementation.
Identify all programs or program units that contain
errors whose detection is required by this Reference Manual;
Discussion: Note that we no longer use
the term “rejection” of programs or program units. We require
that programs or program units with errors or that exceed some capacity
limit be “identified”. The way in which errors or capacity
problems are reported is not specified.
An implementation is allowed to use standard
error-recovery techniques. We do not disallow such techniques from being
used across
compilation_unit
or
compilation
boundaries.
See also the Implementation Requirements of
10.2, which disallow the execution of illegal
partitions.
Supply all language-defined library units required
by this Reference Manual;
Implementation Note: An implementation
cannot add to or modify the visible part of a language-defined library
unit, except where such permission is explicitly granted, unless such
modifications are semantically neutral with respect to the client compilation
units of the library unit. An implementation defines the contents of
the private part and body of language-defined library units.
An implementation can add
with_clauses
and
use_clauses,
since these modifications are semantically neutral to clients. (The implementation
might need
with_clauses
in order to implement the private part, for example.) Similarly, an implementation
can add a private part even in cases where a private part is not shown
in the Reference Manual. Explicit declarations can be provided implicitly
or by renaming, provided the changes are semantically neutral.
Wherever in the Reference
Manual the text of a language-defined library unit contains an italicized
phrase starting with “
implementation-defined”, the
implementation's version will replace that phrase with some implementation-defined
text that is syntactically legal at that place, and follows any other
applicable rules.
Note that modifications are permitted, even
if there are other tools in the environment that can detect the changes
(such as a program library browser), so long as the modifications make
no difference with respect to the static or dynamic semantics of the
resulting programs, as defined by the Reference Manual.
Contain no variations except those explicitly permitted
by this Reference Manual, or those that are impossible or impractical
to avoid given the implementation's execution environment;
Implementation defined: Variations from
the standard that are impractical to avoid given the implementation's
execution environment.
Reason: The “impossible or impractical”
wording comes from AI-325. It takes some judgement and common sense to
interpret this. Restricting compilation units to less than 4 lines is
probably unreasonable, whereas restricting them to less than 4 billion
lines is probably reasonable (at least given today's technology). We
do not know exactly where to draw the line, so we have to make the rule
vague.
Specify all such variations in the manner prescribed
by this Reference Manual.
The
external effect of the execution of an Ada program is defined
in terms of its interactions with its external environment.
The
following are defined as
external interactions:
Any interaction with an external file (see
A.7);
Implementation defined: Which
code_statements
cause external interactions.
Any call on an imported subprogram (see
Annex
B), including any parameters passed to it;
Any result returned or exception propagated from
a main subprogram (see
10.2) or an exported
subprogram (see
Annex B) to an external caller;
Discussion: By “result returned”
we mean to include function results and values returned in [in]
out parameters.
{
8652/0094}
{
AI95-00119-01}
The lack of a result from a program that does not terminate is also included
here.
[Any read or update of an atomic or volatile object
(see
C.6);]
The values of imported and exported objects (see
Annex B) at the time of any other interaction
with the external environment.
To be honest: {
AI05-0229-1}
Also other uses of imported and exported entities, as defined by the
implementation, if the implementation supports such importing or exporting.
A conforming implementation of this Reference
Manual shall produce for the execution of a given Ada program a set of
interactions with the external environment whose order and timing are
consistent with the definitions and requirements of this Reference Manual
for the semantics of the given program.
Ramification: There is no need to produce
any of the “internal effects” defined for the semantics of
the program — all of these can be optimized away — so long
as an appropriate sequence of external interactions is produced.
Discussion: See also
11.6
which specifies various liberties associated with optimizations in the
presence of language-defined checks, that could change the external effects
that might be produced. These alternative external effects are still
consistent with the standard, since
11.6 is
part of the standard.
Note also that we only require “an
appropriate sequence of external interactions” rather than
“the same sequence...” An optimizer may cause a different
sequence of external interactions to be produced than would be produced
without the optimizer, so long as the new sequence still satisfies the
requirements of the standard. For example, optimization might affect
the relative rate of progress of two concurrent tasks, thereby altering
the order in which two external interactions occur.
Note that the Ada 83 RM explicitly mentions
the case of an “exact effect” of a program, but since so
few programs have their effects defined that exactly, we don't even mention
this “special” case. In particular, almost any program that
uses floating point or tasking has to have some level of inexactness
in the specification of its effects. And if one includes aspects of the
timing of the external interactions in the external effect of the program
(as is appropriate for a real-time language), no “exact effect”
can be specified. For example, if two external interactions initiated
by a single task are separated by a “
delay 1.0;” then
the language rules imply that the two external interactions have to be
separated in time by at least one second, as defined by the clock associated
with the
delay_relative_statement.
This in turn implies that the time at which an external interaction occurs
is part of the characterization of the external interaction, at least
in some cases, again making the specification of the required “exact
effect” impractical.
{
AI12-0441-1}
An implementation that conforms to this Reference Manual shall support
each capability required by the core language as specified. In addition,
an implementation that conforms to this Reference Manual may conform
to one or more Specialized Needs Annexes (or to none). Conformance to
a Specialized Needs Annex means that each capability required by the
Annex shall be provided as specified.
Discussion: The last sentence defines
what it means to say that an implementation conforms to a Specialized
Needs Annex, namely, only by supporting all capabilities required by
the Annex.
{
AI05-0229-1}
An implementation conforming to this Reference Manual may provide additional
aspects, attributes, library units, and pragmas. However, it shall not
provide any aspect, attribute, library unit, or pragma having the same
name as an aspect, attribute, library unit, or pragma (respectively)
specified in a Specialized Needs Annex unless the provided construct
is either as specified in the Specialized Needs Annex or is more limited
in capability than that required by the Annex. A program that attempts
to use an unsupported capability of an Annex shall either be identified
by the implementation before run time or shall raise an exception at
run time.
Discussion: The last sentence of the
preceding paragraph defines what an implementation is allowed to do when
it does not "conform" to a Specialized Needs Annex. In particular,
the sentence forbids implementations from providing a construct with
the same name as a corresponding construct in a Specialized Needs Annex
but with a different syntax (e.g., an extended syntax) or quite different
semantics. The phrase concerning "more limited in capability"
is intended to give permission to provide a partial implementation, such
as not implementing a subprogram in a package or having a restriction
not permitted by an implementation that conforms to the Annex. For example,
a partial implementation of the package Ada.Decimal might have Decimal.Max_Decimal_Digits
as 15 (rather than the required 18). This allows a partial implementation
to grow to a fully conforming implementation.
A restricted implementation might be restricted
by not providing some subprograms specified in one of the packages defined
by an Annex. In this case, a program that tries to use the missing subprogram
will usually fail to compile. Alternatively, the implementation might
declare the subprogram as abstract, so it cannot be called. Alternatively,
a subprogram body might be implemented just to raise Program_Error. The
advantage of this approach is that a program to be run under a fully
conforming Annex implementation can be checked syntactically and semantically
under an implementation that only partially supports the Annex. Finally,
an implementation might provide a package declaration without the corresponding
body, so that programs can be compiled, but partitions cannot be built
and executed.
To ensure against wrong answers being delivered
by a partial implementation, implementers are required to raise an exception
when a program attempts to use an unsupported capability and this can
be detected only at run time. For example, a partial implementation of
Ada.Decimal might require the length of the Currency string to be 1,
and hence, an exception would be raised if a subprogram were called in
the package Edited_Output with a length greater than 1.
{
AI12-0179-1}
{
AI12-0265-1}
For an implementation that conforms to this Reference Manual, the implementation
of a language-defined unit shall abide by all postconditions, type invariants,
and default initial conditions specified for the unit by this document
(see
11.4.2).
Documentation Requirements
Certain
aspects of the semantics are defined to be either
implementation defined
or
unspecified. In such cases, the set of possible effects is
specified, and the implementation may choose any effect in the set. Implementations
shall document their behavior in implementation-defined situations, but
documentation is not required for unspecified situations. The implementation-defined
characteristics are summarized in
M.2.
Discussion: We used to use the term “implementation
dependent” instead of “unspecified”. However, that
sounded too much like “implementation defined”. Furthermore,
the term “unspecified” is used in the ANSI C and POSIX standards
for this purpose, so that is another advantage. We also use “not
specified” and “not specified by the language” as synonyms
for “unspecified”. The documentation requirement is the only
difference between implementation defined and unspecified.
Note that the “set of possible effects”
can be “all imaginable effects”, as is the case with erroneous
execution.
The implementation may choose to document implementation-defined
behavior either by documenting what happens in general, or by providing
some mechanism for the user to determine what happens in a particular
case.
Discussion: For example, if the Reference
Manual says that library unit elaboration order is implementation defined,
the implementation might describe (in its user's manual) the algorithm
it uses to determine the elaboration order. On the other hand, the implementation
might provide a command that produces a description of the elaboration
order for a partition upon request from the user. It is also acceptable
to provide cross references to existing documentation (for example, a
hardware manual), where appropriate.
Note that dependence of a program on implementation-defined
or unspecified functionality is not defined to be an error; it might
cause the program to be less portable, however.
Documentation Requirement: The behavior
of implementations in implementation-defined situations shall be documented
— see
M.2 for a listing.
Implementation Advice
If an implementation detects the use of an unsupported
Specialized Needs Annex feature at run time, it should raise Program_Error
if feasible.
Implementation Advice: Program_Error
should be raised when an unsupported Specialized Needs Annex feature
is used at run time.
Reason: The reason we don't require
Program_Error is that there are situations where other exceptions might
make sense. For example, if the Real Time Systems Annex requires that
the range of System.Priority include at least 30 values, an implementation
could conform to the Reference Manual (but not to the Annex) if it supported
only 12 values. Since the rules of the language require Constraint_Error
to be raised for out-of-range values, we cannot require Program_Error
to be raised instead.
If an implementation wishes to provide implementation-defined
extensions to the functionality of a language-defined library unit, it
should normally do so by adding children to the library unit.
Implementation Advice: Implementation-defined
extensions to the functionality of a language-defined library unit should
be provided by adding children to the library unit.
Implementation Note: If an implementation
has support code (“run-time system code”) that is needed
for the execution of user-defined code, it can put that support code
in child packages of System. Otherwise, it has to use some trick to avoid
polluting the user's namespace. It is important that such tricks not
be available to user-defined code (not in the standard mode, at least)
— that would defeat the purpose.
NOTE {
AI12-0440-1}
The above requirements imply that an implementation conforming to this
Reference Manual can support some of the capabilities required by a Specialized
Needs Annex without supporting all required capabilities.
Discussion: A conforming implementation
can partially support a Specialized Needs Annex. Such an implementation
does not conform to the Annex, but it does conform to the Reference Manual.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe