Contents   Index   Search   Previous   Next

1.1.3 Conformity of an Implementation with the Standard

Implementation Requirements

   {conformance (of an implementation with the Standard)} A conforming implementation shall:
Discussion: {implementation} 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 standard. 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 Standard'' -- this requires support for the core language, and allows partial (but not conflicting) support for the Specialized Needs Annexes.
Implementation defined: Capacity limitations of the implementation.
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.
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 standard. Explicit declarations can be provided implicitly or by renaming, provided the changes are semantically neutral.
{italics (implementation-defined)} Wherever in the standard 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 standard.
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.
   {external effect (of the execution of an Ada program)} {effect (external)} The external effect of the execution of an Ada program is defined in terms of its interactions with its external environment. {external interaction} The following are defined as external interactions:
Implementation defined: Which code_statements cause external interactions.
Discussion: By ``result returned'' we mean to include function results and values returned in [in] out parameters.
{8652/0094} {AI95-00119} The lack of a result from a program that does not terminate is also included here.
To be honest: Also other uses of imported and exported entities, as defined by the implementation, if the implementation supports such pragmas.
    A conforming implementation of this International Standard 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 International Standard 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 RM83 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.
    An implementation that conforms to this Standard shall support each capability required by the core language as specified. In addition, an implementation that conforms to this Standard 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 is 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.
    An implementation conforming to this International Standard may provide additional attributes, library units, and pragmas. However, it shall not provide any attribute, library unit, or pragma having the same name as an 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. {Program_Error (raised by failure of run-time check)} 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.

Documentation Requirements

    {implementation defined} {unspecified} {specified (not!)} {implementation-dependent: See unspecified} {documentation (required of an implementation)} 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 Annex M.
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 standard 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.

Implementation Advice

    {Program_Error (raised by failure of run-time check)} If an implementation detects the use of an unsupported Specialized Needs Annex feature at run time, it should raise Program_Error if feasible.
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 Standard (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 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.
2  The above requirements imply that an implementation conforming to this Standard may 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 Standard.

Contents   Index   Search   Previous   Next   Legal