home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-29 | 1.9 MB | 42,837 lines |
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
-
-
-
-
-
- INTERNATIONAL STANDARD ISO/IEC 8652:1995(E)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- INFORMATION TECHNOLOGY -- PROGRAMMING LANGUAGES -- ADA
-
- [Revision of first edition (ISO 8652:1987)]
-
- ANNOTATED
- ADA REFERENCE MANUAL
-
-
- Language and Standard Libraries
-
- Version 5.95
- 25 November 1994
-
-
-
-
-
-
-
-
- Copyright (C) 1992,1993,1994,1995 Intermetrics, Inc.
-
- This copyright is assigned to the U.S. Government. All rights reserved.
-
- This document may be copied, in whole or in part, in any form or by any
- means, as is or with alterations, provided that (1) alterations are clearly
- marked as alterations and (2) this copyright notice is included unmodified in
- any copy. Compiled copies of standard library units and examples need not
- contain this copyright notice so long as the notice is included in all copies
- of source code and documentation.
- INTERNATIONAL ORGANIZATION FOR STANDARDIZATION
- INTERNATIONAL ELECTROTECHNICAL COMMISSION
- Foreword
-
-
- 1 ISO (the International Organization for Standardization) and IEC (the
- International Electrotechnical Commission) form the specialized system for
- worldwide standardization. National bodies that are members of ISO or IEC
- participate in the development of International Standards through technical
- committees established by the respective organization to deal with particular
- fields of technical activity. ISO and IEC technical committees collaborate
- in fields of mutual interest. Other international organizations,
- governmental and non-governmental, in liaison with ISO and IEC, also take
- part in the work.
-
- 2 In the field of information technology, ISO and IEC have established a
- joint technical committee, ISO/IEC JTC 1. Draft International Standards
- adopted by the joint technical committee are circulated to national bodies
- for voting. Publication as an International Standard requires approval by at
- least 75 % of the national bodies casting a vote.
-
- 3 International Standard ISO/IEC 8652 was prepared by Joint Technical
- Committee ISO/IEC JTC 1, Information Technology.
-
- 4 This second edition cancels and replaces the first edition (ISO
- 8652:1987), of which it constitutes a technical revision.
-
- 5 Annexes A to J form an integral part of this International Standard.
- Annexes K to P are for information only.
-
- 5.a Change: Changed Annex letters as per instructions from ISO.
-
- 5.b Discussion: This document is the Annotated Ada Reference
- Manual (AARM). It contains the entire text of the Ada 9X standard
- (ISO/IEC 8652:1995(E)), plus various annotations. It is intended
- primarily for compiler writers, validation test writers, and other
- language lawyers. The annotations include detailed rationale for
- individual rules and explanations of some of the more arcane
- interactions among the rules.
- Introduction
-
-
- 1 This is the Annotated Ada Reference Manual.
-
- 2 Other available Ada documents include:
-
- 3 Rationale for the Ada Programming Language -- 1995 edition, which
- gives an introduction to the new features of Ada, and explains
- the rationale behind them. Programmers should read this first.
-
- 4 The Ada Reference Manual (RM). This is the International
- Standard -- ISO/IEC 8652:1995(E).
-
- 5 Changes to Ada -- 1987 to 1995. This document lists in detail
- the changes made to the 1987 edition of the standard.
-
-
- Design Goals
-
- 6 Ada was originally designed with three overriding concerns: program
- reliability and maintenance, programming as a human activity, and efficiency.
- This revision to the language was designed to provide greater flexibility and
- extensibility, additional control over storage management and synchroniza-
- tion, and standardized packages oriented toward supporting important
- application areas, while at the same time retaining the original emphasis on
- reliability, maintainability, and efficiency.
-
- 7 The need for languages that promote reliability and simplify maintenance
- is well established. Hence emphasis was placed on program readability over
- ease of writing. For example, the rules of the language require that program
- variables be explicitly declared and that their type be specified. Since the
- type of a variable is invariant, compilers can ensure that operations on
- variables are compatible with the properties intended for objects of the
- type. Furthermore, error-prone notations have been avoided, and the syntax
- of the language avoids the use of encoded forms in favor of more English-like
- constructs. Finally, the language offers support for separate compilation of
- program units in a way that facilitates program development and maintenance,
- and which provides the same degree of checking between units as within a
- unit.
-
- 8 Concern for the human programmer was also stressed during the design.
- Above all, an attempt was made to keep to a relatively small number of
- underlying concepts integrated in a consistent and systematic way while
- continuing to avoid the pitfalls of excessive involution. The design
- especially aims to provide language constructs that correspond intuitively to
- the normal expectations of users.
-
- 9 Like many other human activities, the development of programs is becoming
- ever more decentralized and distributed. Consequently, the ability to
- assemble a program from independently produced software components continues
- to be a central idea in the design. The concepts of packages, of private
- types, and of generic units are directly related to this idea, which has
- ramifications in many other aspects of the language. An allied concern is
- the maintenance of programs to match changing requirements; type extension
- and the hierarchical library enable a program to be modified while minimizing
- disturbance to existing tested and trusted components.
-
- 10 No language can avoid the problem of efficiency. Languages that require
- over-elaborate compilers, or that lead to the inefficient use of storage or
- execution time, force these inefficiencies on all machines and on all
- programs. Every construct of the language was examined in the light of
- present implementation techniques. Any proposed construct whose
- implementation was unclear or that required excessive machine resources was
- rejected.
-
-
- Language Summary
-
- 11 An Ada program is composed of one or more program units. Program units
- may be subprograms (which define executable algorithms), packages (which
- define collections of entities), task units (which define concurrent
- computations), protected units (which define operations for the coordinated
- sharing of data between tasks), or generic units (which define parameterized
- forms of packages and subprograms). Each program unit normally consists of
- two parts: a specification, containing the information that must be visible
- to other units, and a body, containing the implementation details, which need
- not be visible to other units. Most program units can be compiled
- separately.
-
- 12 This distinction of the specification and body, and the ability to
- compile units separately, allows a program to be designed, written, and
- tested as a set of largely independent software components.
-
- 13 An Ada program will normally make use of a library of program units of
- general utility. The language provides means whereby individual
- organizations can construct their own libraries. All libraries are
- structured in a hierarchical manner; this enables the logical decomposition
- of a subsystem into individual components. The text of a separately compiled
- program unit must name the library units it requires.
-
- 14 Program Units
-
- 15 A subprogram is the basic unit for expressing an algorithm. There are
- two kinds of subprograms: procedures and functions. A procedure is the means
- of invoking a series of actions. For example, it may read data, update
- variables, or produce some output. It may have parameters, to provide a
- controlled means of passing information between the procedure and the point
- of call. A function is the means of invoking the computation of a value. It
- is similar to a procedure, but in addition will return a result.
-
- 16 A package is the basic unit for defining a collection of logically
- related entities. For example, a package can be used to define a set of type
- declarations and associated operations. Portions of a package can be hidden
- from the user, thus allowing access only to the logical properties expressed
- by the package specification.
-
- 17 Subprogram and package units may be compiled separately and arranged in
- hierarchies of parent and child units giving fine control over visibility of
- the logical properties and their detailed implementation.
-
- 18 A task unit is the basic unit for defining a task whose sequence of
- actions may be executed concurrently with those of other tasks. Such tasks
- may be implemented on multicomputers, multiprocessors, or with interleaved
- execution on a single processor. A task unit may define either a single
- executing task or a task type permitting the creation of any number of
- similar tasks.
-
- 19 A protected unit is the basic unit for defining protected operations for
- the coordinated use of data shared between tasks. Simple mutual exclusion is
- provided automatically, and more elaborate sharing protocols can be defined.
- A protected operation can either be a subprogram or an entry. A protected
- entry specifies a Boolean expression (an entry barrier) that must be true
- before the body of the entry is executed. A protected unit may define a
- single protected object or a protected type permitting the creation of
- several similar objects.
-
- 20 Declarations and Statements
-
- 21 The body of a program unit generally contains two parts: a declarative
- part, which defines the logical entities to be used in the program unit, and
- a sequence of statements, which defines the execution of the program unit.
-
- 22 The declarative part associates names with declared entities. For
- example, a name may denote a type, a constant, a variable, or an exception.
- A declarative part also introduces the names and parameters of other nested
- subprograms, packages, task units, protected units, and generic units to be
- used in the program unit.
-
- 23 The sequence of statements describes a sequence of actions that are to
- be performed. The statements are executed in succession (unless a transfer
- of control causes execution to continue from another place).
-
- 24 An assignment statement changes the value of a variable. A procedure
- call invokes execution of a procedure after associating any actual parameters
- provided at the call with the corresponding formal parameters.
-
- 25 Case statements and if statements allow the selection of an enclosed
- sequence of statements based on the value of an expression or on the value of
- a condition.
-
- 26 The loop statement provides the basic iterative mechanism in the
- language. A loop statement specifies that a sequence of statements is to be
- executed repeatedly as directed by an iteration scheme, or until an exit
- statement is encountered.
-
- 27 A block statement comprises a sequence of statements preceded by the
- declaration of local entities used by the statements.
-
- 28 Certain statements are associated with concurrent execution. A delay
- statement delays the execution of a task for a specified duration or until a
- specified time. An entry call statement is written as a procedure call
- statement; it requests an operation on a task or on a protected object,
- blocking the caller until the operation can be performed. A called task may
- accept an entry call by executing a corresponding accept statement, which
- specifies the actions then to be performed as part of the rendezvous with the
- calling task. An entry call on a protected object is processed when the
- corresponding entry barrier evaluates to true, whereupon the body of the
- entry is executed. The requeue statement permits the provision of a service
- as a number of related activities with preference control. One form of the
- select statement allows a selective wait for one of several alternative
- rendezvous. Other forms of the select statement allow conditional or timed
- entry calls and the asynchronous transfer of control in response to some
- triggering event.
-
- 29 Execution of a program unit may encounter error situations in which
- normal program execution cannot continue. For example, an arithmetic
- computation may exceed the maximum allowed value of a number, or an attempt
- may be made to access an array component by using an incorrect index value.
- To deal with such error situations, the statements of a program unit can be
- textually followed by exception handlers that specify the actions to be taken
- when the error situation arises. Exceptions can be raised explicitly by a
- raise statement.
-
- 30 Data Types
-
- 31 Every object in the language has a type, which characterizes a set of
- values and a set of applicable operations. The main classes of types are
- elementary types (comprising enumeration, numeric, and access types) and
- composite types (including array and record types).
-
- 32 An enumeration type defines an ordered set of distinct enumeration
- literals, for example a list of states or an alphabet of characters. The
- enumeration types Boolean, Character, and Wide_Character are predefined.
-
- 33 Numeric types provide a means of performing exact or approximate
- numerical computations. Exact computations use integer types, which denote
- sets of consecutive integers. Approximate computations use either fixed
- point types, with absolute bounds on the error, or floating point types, with
- relative bounds on the error. The numeric types Integer, Float, and Duration
- are predefined.
-
- 34 Composite types allow definitions of structured objects with related
- components. The composite types in the language include arrays and records.
- An array is an object with indexed components of the same type. A record is
- an object with named components of possibly different types. Task and
- protected types are also forms of composite types. The array types String
- and Wide_String are predefined.
-
- 35 Record, task, and protected types may have special components called
- discriminants which parameterize the type. Variant record structures that
- depend on the values of discriminants can be defined within a record type.
-
- 36 Access types allow the construction of linked data structures. A value
- of an access type represents a reference to an object declared as aliased or
- to an object created by the evaluation of an allocator. Several variables of
- an access type may designate the same object, and components of one object
- may designate the same or other objects. Both the elements in such linked
- data structures and their relation to other elements can be altered during
- program execution. Access types also permit references to subprograms to be
- stored, passed as parameters, and ultimately dereferenced as part of an
- indirect call.
-
- 37 Private types permit restricted views of a type. A private type can be
- defined in a package so that only the logically necessary properties are made
- visible to the users of the type. The full structural details that are
- externally irrelevant are then only available within the package and any
- child units.
-
- 38 From any type a new type may be defined by derivation. A type, together
- with its derivatives (both direct and indirect) form a derivation class.
- Class-wide operations may be defined that accept as a parameter an operand of
- any type in a derivation class. For record and private types, the
- derivatives may be extensions of the parent type. Types that support these
- object-oriented capabilities of class-wide operations and type extension must
- be tagged, so that the specific type of an operand within a derivation class
- can be identified at run time. When an operation of a tagged type is applied
- to an operand whose specific type is not known until run time, implicit
- dispatching is performed based on the tag of the operand.
-
- 39 The concept of a type is further refined by the concept of a subtype,
- whereby a user can constrain the set of allowed values of a type. Subtypes
- can be used to define subranges of scalar types, arrays with a limited set of
- index values, and records and private types with particular discriminant
- values.
-
- 40 Other Facilities
-
- 41 Representation clauses can be used to specify the mapping between types
- and features of an underlying machine. For example, the user can specify
- that objects of a given type must be represented with a given number of bits,
- or that the components of a record are to be represented using a given
- storage layout. Other features allow the controlled use of low level,
- nonportable, or implementation-dependent aspects, including the direct
- insertion of machine code.
-
- 42 The predefined environment of the language provides for input-output and
- other capabilities (such as string manipulation and random number generation)
- by means of standard library packages. Input-output is supported for values
- of user-defined as well as of predefined types. Standard means of
- representing values in display form are also provided. Other standard
- library packages are defined in annexes of the standard to support systems
- with specialized requirements.
-
- 43 Finally, the language provides a powerful means of parameterization of
- program units, called generic program units. The generic parameters can be
- types and subprograms (as well as objects and packages) and so allow general
- algorithms and data structures to be defined that are applicable to all types
- of a given class.
-
-
- Language Changes
-
- 44 This International Standard replaces the first edition of 1987. In this
- edition, the following major language changes have been incorporated:
-
- 45 Support for standard 8-bit and 16-bit character sets. See
- Section 2, 3.5.2, 3.6.3, A.1, A.3, and A.4.
-
- 46 Object-oriented programming with run-time polymorphism. See the
- discussions of classes, derived types, tagged types, record
- extensions, and private extensions in clauses 3.4, 3.9, and 7.3.
- See also the new forms of generic formal parameters that are
- allowed by 12.5.1, ``Formal Private and Derived Types'' and 12.7,
- ``Formal Packages''.
-
- 47 Access types have been extended to allow an access value to
- designate a subprogram or an object declared by an object
- declaration (as opposed to just a heap-allocated object). See
- 3.10.
-
- 48 Efficient data-oriented synchronization is provided via protected
- types. See Section 9.
-
- 49 The library units of a library may be organized into a hierarchy
- of parent and child units. See Section 10.
-
- 50 Additional support has been added for interfacing to other
- languages. See Annex B.
-
- 51 The Specialized Needs Annexes have been added to provide specific
- support for certain application areas:
-
- 52 Annex C, ``Systems Programming''
-
- 53 Annex D, ``Real-Time Systems''
-
- 54 Annex E, ``Distributed Systems''
-
- 55 Annex F, ``Information Systems''
-
- 56 Annex G, ``Numerics''
-
- 57 Annex H, ``Safety and Security''
-
- 58 For a more detailed list of changes, see the Changes to Ada -- 1987 to
- 1995 document.
- Instructions for Comment Submission
-
- 59 {instructions for comment submission} {comments, instructions for
- submission} Informal comments on this International Standard may be sent via
- e-mail to ada-comment@sei.cmu.edu. If appropriate, the Project Editor will
- initiate a Technical Corrigendum to be issued for the standard.
-
- 60 Comments should use the following format:
-
- 61
- !topic Title summarizing comment
- !reference RM95-ss.ss(pp)
- !from Author Name yy-mm-dd
- !keywords keywords related to topic
- !discussion
-
- text of discussion
-
- 61.a Change: Removed ";5.95" from the !reference line.
-
- 62 where ss.ss is the section, clause or subclause number, pp is the
- paragraph number where applicable, and yy-mm-dd is the date the comment was
- sent. The date is optional, as is the !keywords line.
-
- 63 Multiple comments per e-mail message are acceptable. Please use a
- descriptive ``Subject'' in your e-mail message.
-
- 64 When correcting typographical errors or making minor wording
- suggestions, please put the correction directly as the topic of the comment;
- use square brackets [ ] to indicate text to be omitted and curly braces { }
- to indicate text to be added, and provide enough context to make the nature
- of the suggestion self-evident or put additional information in the body of
- the comment, for example:
-
- 65
- !topic [c]{C}haracter
- !topic it[']s meaning is not defined
-
- 66 Formal requests for interpretations and for reporting defects in this
- International Standard may be made in accordance with the ISO/IEC JTC1
- Directives and the ISO/IEC JTC1/SC22 policy for interpretations. ISO Member
- Bodies may submit a Defect Report to ISO for resolution under the JTC1 and
- JTC1/SC22 procedures. A response will be provided and, if appropriate, a
- Technical Corrigendum will be issued through JTC1.
- Acknowledgements
-
- 67 This International Standard was prepared by the Ada 9X Mapping/Revision
- Team based at Intermetrics, Inc., which has included: W. Carlson, Program
- Manager; T. Taft, Technical Director; J. Barnes (consultant); B. Brosgol
- (consultant); R. Duff (Oak Tree Software); M. Edwards; C. Garrity;
- R. Hilliard; O. Pazy (consultant); D. Rosenfeld; L. Shafer; W. White;
- M. Woodger.
-
- 68 The following consultants to the Ada 9X Project contributed to the
- Specialized Needs Annexes: T. Baker (Real-Time/Systems Programming -- SEI,
- FSU); K. Dritz (Numerics -- Argonne National Laboratory); A. Gargaro
- (Distributed Systems -- Computer Sciences); J. Goodenough (Real-Time/Systems
- Programming -- SEI); J. McHugh (Secure Systems -- consultant); B. Wichmann
- (Safety-Critical Systems -- NPL: UK).
-
- 69 This work was regularly reviewed by the Ada 9X Distinguished Reviewers
- and the members of the Ada 9X Rapporteur Group (XRG): E. Ploedereder,
- Chairman of DRs and XRG (University of Stuttgart: Germany); B. Bardin
- (Hughes); J. Barnes (consultant: UK); B. Brett (DEC); B. Brosgol
- (consultant); R. Brukardt (RR Software); N. Cohen (IBM); R. Dewar (NYU);
- G. Dismukes (TeleSoft); A. Evans (consultant); A. Gargaro (Computer
- Sciences); M. Gerhardt (ESL); J. Goodenough (SEI); S. Heilbrunner (University
- of Salzburg: Austria); P. Hilfinger (UC/Berkeley); B. Kaellberg (CelsiusTech:
- Sweden); M. Kamrad II (Unisys); J. van Katwijk (Delft University of
- Technology: The Netherlands); V. Kaufman (Russia); P. Kruchten (Rational);
- R. Landwehr (CCI: Germany); C. Lester (Portsmouth Polytechnic: UK);
- L. Mansson (TELIA Research: Sweden); S. Michell (Multiprocessor Toolsmiths:
- Canada); M. Mills (US Air Force); D. Pogge (US Navy); K. Power (Boeing);
- O. Roubine (Verdix: France); A. Strohmeier (Swiss Fed Inst of Technology:
- Switzerland); W. Taylor (consultant: UK); J. Tokar (Tartan); E. Vasilescu
- (Grumman); J. Vladik (Prospeks s.r.o.: Czech Republic); S. Van Vlierberghe
- (OFFIS: Belgium).
-
- 69.a Change: Various changes at the request of some people
- mentioned above, and Chris Anderson.
-
- 70 Other valuable feedback influencing the revision process was provided by
- the Ada 9X Language Precision Team (Odyssey Research Associates), the Ada 9X
- User/Implementer Teams (AETECH, Tartan, TeleSoft), the Ada 9X Implementation
- Analysis Team (New York University) and the Ada community-at-large.
-
- 71 Special thanks go to R. Mathis, Convenor of ISO/IEC JTC1/SC22 Working
- Group 9.
-
- 72 The Ada 9X Project was sponsored by the Ada Joint Program Office.
- Christine M. Anderson at the Air Force Phillips Laboratory (Kirtland AFB, NM)
- was the project manager.
- Changes Since Version 5.0
-
- 73 Changes since version 5.0 of 3 June 1994 are marked with change bars.
- Thick change bars, like the one next to this paragraph, indicate changes that
- might affect an implementation.
-
- 74 Thin change bars, like the one next to this paragraph, indicate changes,
- such as minor wording changes, that would be unlikely to affect an
- implementation. Change bars are not included in the ASCII version.
-
- 75 There are some formatting changes that are not marked. In addition, we
- have made no attempt to mark changes in summary material, such as the Index
- or the Informative Annexes; the change bars found in those places are
- incomplete.
-
- 76 The document submitted to ISO for publication as the International
- Standard is the same as this version, except:
-
- 77 This list of ``Changes Since Version 5.0'' is not included in the
- International Standard.
-
- 78 The International Standard does not have change bars.
-
- 79 The list of changes in the Index is not included in the
- International Standard.
-
- 80 The ``Acknowledgements'' page is not included in the
- International Standard.
-
- 81 The text in the running headers and footers on each page is
- slightly different in the International Standard.
-
- 82 The title page(s) are different in the International Standard.
-
- 83 This document is formatted for 8.5-by-11-inch paper, whereas the
- International Standard is formatted for A4 paper (210-by-297mm);
- thus, the page breaks are in different places.
-
- 84 Additional formatting changes may be required by ISO before final
- publication of the International Standard.
-
- 85 These are the changes marked with thick change bars:
-
- 86 An implementation of floating point may support infinities and
- NaNs in Wide_Value, Value, and Get (see 3.5 and A.10.9).
-
- 87 The Wide_Width attribute is added (see 3.5).
-
- 88 An implementation requirement on System.Max_Binary_Modulus was
- added, so at least 16-bit binary modular types have to be
- supported (see 3.5.4).
-
- 89 S'Base'Digits now yields the requested decimal precision of the
- base subtype (see 3.5.7 and 3.5.8).
-
- 90 An abstract subprogram (or primitive function with controlling
- result) need not be overridden for a generic formal tagged
- nonabstract type (see 3.9.3).
-
- 91 A generic formal object of a tagged type is aliased (see 3.10 and
- 3.10.2).
-
- 92 An incomplete type is now allowed in an access_to_subprogram_
- definition (see 3.10.1).
-
- 93 The accessibility rules have been rewritten. The intended effect
- has not changed, but the wording is quite different. See 3.10.2.
- See also 3.9.1, 4.6, 6.5, 7.6.1, and 9.5.4. As part of this
- change, the definition of the term ``master'' was slightly
- changed (see 7.6.1, 9.3, 9.8, and 10.2).
-
- 94 The rule about taking 'Access of a discriminant-dependent
- component has been changed to match the corresponding rule for
- renaming. The rule about P'Access when P is within a generic has
- been changed to refer to the generic body instead of the generic
- unit. See 3.10.2.
-
- 95 The static expression rules were clarified, and a few bugs were
- fixed (see 4.9).
-
- 96 The rule about multiple access paths has been clarified (see
- 6.2).
-
- 97 An inherited subprogram of a generic formal tagged type with
- unknown discriminants is now defined to be intrinsic. In
- addition, operators defined in language-defined library units may
- be intrinsic. See 6.3.1. Ada.Decimal.Divide is also intrinsic
- (see F.2).
-
- 98 The definition of subtype conformance no longer includes a
- special case for convention Intrinsic. Instead, the special case
- has been moved to the relevant specific rules. See 6.3.1. See
- also 3.9.2, 3.10.2, 8.5.4, 12.3, and 13.3.
-
- 99 The definition of full conformance was corrected to include
- character_literals. The relationship with functional vs.
- operator notation was clarified in the AARM. See 6.3.1.
-
- 100 The rule about when copy-in is required for composite out
- parameters passed by copy was corrected (see 6.4.1).
-
- 101 The rule about when a full view has to be limited was clarified.
- Some bugs were fixed in the rules about correspondence of
- discriminants between partial and full views. See 7.3.
-
- 102 Ada.Finalization is now preelaborated (see 7.6).
-
- 103 The Implementation Permission to omit code for (e.g.) ``X := X;''
- was clarified (see 7.6).
-
- 104 Things like ``X: T'Class renames Y;'', where Y is of type T, are
- now illegal (see 8.5.1). An analogous change was made to generic
- formal objects of mode in out (see 12.4).
-
- 105 The visible part of a task or protected unit includes the
- discriminant part, if any (see 9.1 and 9.4).
-
- 106 The definition of when a task doing an entry call is ``blocked''
- has been clarified (see 9.5.3).
-
- 107 A library unit subprogram renaming declaration is always a
- renaming-as-declaration, never a renaming-as-body (see 10.1.1).
-
- 108 The rules about children of generic packages were changed. See
- 10.1.1. See also 8.3, 10.1.2, 10.1.6, and 12.2.
-
- 109 An AARM annotation was added clarifying the intent that it is
- illegal for a library subprogram_body with no corresponding
- subprogram_declaration to mention one of its siblings in a with_
- clause if the sibling is a private library unit (see 10.1.2).
-
- 110 Library unit names must be unique (see 10.1.4).
-
- 111 Exception_Name(Constraint_Error'Identity) returns "Constraint_
- Error". Information is not duplicated among Exception_Name,
- Exception_Message, and Exception_Information. See 11.4.1.
-
- 112 Legality Rules are re-checked in the formal part of an instance
- (see 12.3).
-
- 113 The rules for discriminant matching in formal private and derived
- types were corrected (see 12.5.1).
-
- 114 Changes were made to the semantics of the Size attribute and
- clause, and some advice that appeared only in Implementation
- Notes in the AARM was moved to Implementation Advice in the RM95
- (see 13.3).
-
- 115 An implementation is allowed (but not required) to declare
- packages System and System.Storage_Elements pure (see 13.7 and
- 13.7.1).
-
- 116 Address_To_Access_Conversions is now a library package instead of
- a nested package, and is preelaborated (see 13.7.2).
-
- 117 Unchecked_Conversion is declared pure (see 13.9).
-
- 118 The rules for dereferencing access values designating nonexistent
- objects were corrected (see 13.9.1 and 13.11.2).
-
- 119 Unchecked_Deallocation is preelaborated (see 13.11.2).
-
- 120 The external representation used by 'Write and 'Read has been
- decoupled from the internal representation implied by
- representation items, and the legality rules for representation
- clauses for the stream-related have changed (see 13.13.2 and
- 13.3).
-
- 121 Added an AARM annotation clarifying that an implementation may,
- for example, define the Small of type Duration (see A.1).
-
- 122 The package Ada.Characters.Handling is specified with pragma
- Preelaborate, rather than with pragma Pure (see A.3.2).
-
- 123 Wording of the Wide_Character test functions has been revised to
- avoid overspecification of the relationship between Character and
- Wide_Character ranges (see A.3.2).
-
- 124 Names for the control character positions in Characters.Latin_1
- have been corrected (see A.3.3).
-
- 125 The package Strings.Unbounded is specified with pragma
- Preelaborate (see A.4.5).
-
- 126 The package Strings.Maps.Constants is now a child of
- Strings.Maps, and analogously Strings.Wide_Maps.Wide_Constants is
- now a child of Strings.Wide_Maps; the types of the parameters and
- results for several of the Wide_String handling functions have
- been corrected (see A.4.6 and A.4.7).
-
- 127 The Set_Input, Set_Output, and Set_Error procedures that take a
- parameter of type File_Access have been removed from Text_IO (see
- A.10.1).
-
- 128 Input-output for numeric types has been revised with respect to
- the treatment of signs for input with modular types, the
- treatment of signed zeros and other special values for floating
- point input-output, and rounding and accuracy requirements for
- real output (see A.10.8 and A.10.9).
-
- 129 The effect of enumeration output for a character type has been
- clarified (see A.10.10).
-
- 130 Preinstantiations of the numeric IO packages are provided for the
- predefined numeric types (see A.10.8, A.10.9, and A.11).
-
- 131 Added the package Wide_Text_IO.Text_Streams (see A.12.3).
-
- 132 Renamed items in package Command_Line (see A.15).
-
- 133 An AARM-only annotation has been added advising the
- implementation on the names to choose for IEEE floating point
- types (see B.2).
-
- 134 The packages Interfaces.C, Interfaces.C.Strings, and
- Interfaces.C.Pointers include several small enhancements (see
- B.3, B.3.1, and B.3.2).
-
- 135 Corrected a parameter type in Decimal_Conversions (see B.4).
-
- 136 The semantics of pragma Discard_Names has been corrected (see
- C.5).
-
- 137 Implementation permissions related to blocking have been added to
- D.2.1 and D.2.2.
-
- 138 The restrictions on remote types library units now apply only to
- the declaration and not to the body. Remote access types may now
- be declared in remote types packages. See Annex E.
-
- 139 The implementation model in the AARM for remote procedure calls
- has been clarified (see E.4).
-
- 140 Added a partition id parameter to Establish_RPC_Receiver (see
- E.5).
-
- 141 Added an AARM note on the intent of the support for decimal
- Machine_Radix (see F.1).
-
- 142 Removed incorrect restriction on the form of a picture string
- (see F.3.1).
-
- 143 Removed obsolete declaration from Text_IO.Editing (see F.3.3).
-
- 144 Revised the description of the model-oriented attributes for
- floating point types (see G.2.2).
-
- 145 Revised the treatment of conversion of fixed point multiplication
- and division to an integer result (see G.2.3).
-
- 146 Corrected some bugs in the rules of J.3, ``Reduced Accuracy
- Subtypes''.
-
-
-
- ----------------------
- INTERNATIONAL STANDARD
- ----------------------
-
-
-
-
-
-
-
-
-
-
-
- Information technology -- Programming
- Languages -- Ada --
-
-
-
-
-
-
-
-
- Section 1: General
-
-
- 1 Ada is a programming language designed to support the construction of
- long-lived, highly reliable software systems. The language includes
- facilities to define packages of related types, objects, and operations. The
- packages may be parameterized and the types may be extended to support the
- construction of libraries of reusable, adaptable software components. The
- operations may be implemented as subprograms using conventional sequential
- control structures, or as entries that include synchronization of concurrent
- threads of control as part of their invocation. The language treats
- modularity in the physical sense as well, with a facility to support separate
- compilation.
-
- 2 The language includes a complete facility for the support of real-time,
- concurrent programming. Errors can be signaled as exceptions and handled
- explicitly. The language also covers systems programming; this requires
- precise control over the representation of data and access to
- system-dependent properties. Finally, a predefined environment of standard
- packages is provided, including facilities for, among others, input-output,
- string manipulation, numeric elementary functions, and random number
- generation.
-
- 2.a Discussion: This Annotated Ada Reference Manual (AARM)
- contains the entire text of the Ada Reference Manual (RM9X), plus
- certain annotations. The annotations give a more in-depth analysis
- of the language. They describe the reason for each non-obvious rule,
- and point out interesting ramifications of the rules and interactions
- among the rules (interesting to language lawyers, that is).
- Differences between Ada 83 and Ada 9X are listed. (The text you are
- reading now is an annotation.)
-
- 2.b The AARM stresses detailed correctness and uniformity over
- readability and understandability. We're not trying to make the
- language ``appear'' simple here; on the contrary, we're trying to
- expose hidden complexities, so we can more easily detect language
- bugs. The RM9X, on the other hand, is intended to be a more readable
- document for programmers.
-
- 2.c The annotations in the AARM are as follows:
-
- 2.d Text that is logically redundant is shown [in square
- brackets, like this]. Technically, such text could be
- written as a Note in the RM9X, since it is really a
- theorem that can be proven from the non-redundant rules
- of the language. We use the square brackets instead when
- it seems to make the RM9X more readable.
-
- 2.e The rules of the language (and some AARM-only text) are
- categorized, and placed under certain sub-headings that
- indicate the category. For example, the distinction
- between Name Resolution Rules and Legality Rules is
- particularly important, as explained in 8.6.
-
- 2.f Text under the following sub-headings appears in both
- documents:
-
- 2.g The unlabeled text at the beginning of each clause
- or subclause,
- 2.h Syntax,
- 2.i Name Resolution Rules,
- 2.j Legality Rules,
- 2.k Static Semantics,
- 2.l Post-Compilation Rules,
- 2.m Dynamic Semantics,
- 2.n Bounded (Run-Time) Errors,
- 2.o Erroneous Execution,
- 2.p Implementation Requirements,
- 2.q Documentation Requirements,
- 2.r Metrics,
- 2.s Implementation Permissions,
- 2.t Implementation Advice,
- 2.u NOTES,
- 2.v Examples.
-
- 2.w Text under the following sub-headings does not appear in
- the RM9X:
-
- 2.x Language Design Principles,
- 2.y Inconsistencies With Ada 83,
- 2.z Incompatibilities With Ada 83,
- 2.aa Extensions to Ada 83,
- 2.bb Wording Changes From Ada 83.
-
- 2.cc The AARM also includes the following kinds of
- annotations. These do not necessarily annotate the
- immediately preceding rule, although they often do.
-
- 2.dd Reason: An explanation of why a certain rule is necessary, or
- why it is worded in a certain way.
-
- 2.ee Ramification: An obscure ramification of the rules that is of
- interest only to language lawyers. (If a ramification of the rules
- is of interest to programmers, then it appears under NOTES.)
-
- 2.ff Proof: An informal proof explaining how a given Note or
- [marked-as-redundant] piece of text follows from the other rules of
- the language.
-
- 2.gg Implementation Note: A hint about how to implement a feature,
- or a particular potential pitfall that an implementer needs to be
- aware of.
-
- 2.hh Change: Changes to the Ada Reference Manual are annotated
- with one of these when more explanation is needed than the comment
- that triggered the change. Changes are also marked with the database
- number of the comment that triggered the change, like this:
- {95-9999.a} , unless the change is a spelling or grammar correction,
- a correction of Ada syntax in an example, a font change, a change to
- the index or other summary material, or a change that appears only in
- the AARM. Changes are also marked with change bars, even if there is
- no corresponding comment in the database. However, changes to the
- index or other summary material are not always marked with change
- bars.
-
- 2.ii Discussion: Other annotations not covered by the above.
-
- 2.jj To be honest: A rule that is considered logically necessary
- to the definition of the language, but which is so obscure or
- pedantic that only a language lawyer would care. These are the only
- annotations that could be considered part of the language definition.
-
- 2.kk Glossary entry: The text of a Glossary entry -- this text
- will also appear in Annex N, ``Glossary''.
-
- 2.ll Discussion: In general, RM9X text appears in the normal font,
- whereas AARM-only text appears in a smaller font. Notes also appear
- in the smaller font, as recommended by ISO/IEC style guidelines. Ada
- examples are also usually printed in a smaller font.
-
- 2.mm If you have trouble finding things, be sure to use the index.
- {italics, like this} Each defined term appears there, and also in
- italics, like this. Syntactic categories defined in BNF are also
- indexed.
-
- 2.nn A definition marked ``[distributed]'' is the main definition
- for a term whose complete definition is given in pieces distributed
- throughout the document. The pieces are marked ``[partial]'' or with
- a phrase explaining what cases the partial definition applies to.
-
-
-
- 1.1 Scope
-
- 1 This International Standard specifies the form and meaning of programs
- written in Ada. Its purpose is to promote the portability of Ada programs to
- a variety of data processing systems.
-
-
-
- 1.1.1 Extent
-
- 1 This International Standard specifies:
-
- 2 The form of a program written in Ada;
-
- 3 The effect of translating and executing such a program;
-
- 4 The manner in which program units may be combined to form Ada
- programs;
-
- 5 The language-defined library units that a conforming implemen-
- tation is required to supply;
-
- 6 The permissible variations within the standard, and the manner in
- which they are to be documented;
-
- 7 Those violations of the standard that a conforming implementation
- is required to detect, and the effect of attempting to translate
- or execute a program containing such violations;
-
- 8 Those violations of the standard that a conforming implementation
- is not required to detect.
-
- 9 This International Standard does not specify:
-
- 10 The means whereby a program written in Ada is transformed into
- object code executable by a processor;
-
- 11 The means whereby translation or execution of programs is invoked
- and the executing units are controlled;
-
- 12 The size or speed of the object code, or the relative execution
- speed of different language constructs;
-
- 13 The form or contents of any listings produced by implementations;
- in particular, the form or contents of error or warning messages;
-
- 14 The effect of unspecified execution.
-
- 15 The size of a program or program unit that will exceed the
- capacity of a particular conforming implementation.
-
-
-
- 1.1.2 Structure
-
- 1 This International Standard contains thirteen sections, fourteen annexes,
- and an index.
-
- 2 {core language} The core of the Ada language consists of:
-
- 3 Sections 1 through 13
-
- 4 Annex A, ``Predefined Language Environment''
-
- 5 Annex B, ``Interface to Other Languages''
-
- 6 Annex J, ``Obsolescent Features''
-
- 7 {Specialized Needs Annexes} {Annex (Specialized Needs)} {application
- areas} The following Specialized Needs Annexes define features that are
- needed by certain application areas:
-
- 8 Annex C, ``Systems Programming''
-
- 9 Annex D, ``Real-Time Systems''
-
- 10 Annex E, ``Distributed Systems''
-
- 11 Annex F, ``Information Systems''
-
- 12 Annex G, ``Numerics''
-
- 13 Annex H, ``Safety and Security''
-
- 14 {normative} {Annex (normative)} The core language and the Specialized
- Needs Annexes are normative, except that the material in each of the items
- listed below is informative:
-
- 15 Text under a NOTES or Examples heading.
-
- 16 Each clause or subclause whose title starts with the word
- ``Example'' or ``Examples''.
-
- 17 All implementations shall conform to the core language. In addition, an
- implementation may conform separately to one or more Specialized Needs
- Annexes.
-
- 18 {informative} {non-normative: see informative} {Annex (informative)} The
- following Annexes are informative:
-
- 19 Annex K, ``Language-Defined Attributes''
-
- 20 Annex L, ``Language-Defined Pragmas''
-
- 21 Annex M, ``Implementation-Defined Characteristics''
-
- 22 Annex N, ``Glossary''
-
- 23 Annex P, ``Syntax Summary''
-
- 23.a Discussion: The idea of the Specialized Needs Annexes is that
- implementations can choose to target certain application areas. For
- example, an implementation specifically targeted to embedded machines
- might support the application-specific features for Real-time
- Systems, but not the application-specific features for Information
- Systems.
-
- 23.b The Specialized Needs Annexes extend the core language only in
- ways that users, implementations, and standards bodies are allowed to
- extend the language; for example, via additional library units,
- attributes, representation items (see 13.1), pragmas, and constraints
- on semantic details that are left unspecified by the core language.
- Many implementations already provide much of the functionality
- defined by Specialized Needs Annexes; our goal is to increase
- uniformity among implementations by defining standard ways of
- providing the functionality.
-
- 23.c We recommend that the validation procedures allow implemen-
- tations to validate the core language, plus any set of the
- Specialized Needs Annexes. We recommend that implementations not be
- allowed to validate a portion of one of the Specialized Needs
- Annexes, although implementations can, of course, provide unvalidated
- support for such portions. We have designed the Specialized Needs
- Annexes assuming that this recommendation is followed. Thus, our
- decisions about what to include and what not to include in those
- annexes are based on the assumption that each annex is validated in
- an ``all-or-nothing'' manner.
-
- 23.d An implementation may, of course, support extensions that are
- different from (but possibly related to) those defined by one of the
- Specialized Needs Annexes. We recommend that, where appropriate,
- implementations do this by adding library units that are children of
- existing language-defined library packages.
-
- 23.e An implementation should not provide extensions that conflict
- with those defined in the Specialized Needs Annexes, in the following
- sense: Suppose an implementation supports a certain error-free
- program that uses only functionality defined in the core and in the
- Specialized Needs Annexes. The implementation should ensure that
- that program will still be error free in some possible full
- implementation of all of the Specialized Needs Annexes, and that the
- semantics of the program will not change. For example, an
- implementation should not provide a package with the same name as one
- defined in one of the Specialized Needs Annexes, but that behaves
- differently, even if that implementation does not claim conformance
- to that Annex.
-
- 23.f Note that the Specialized Needs Annexes do not conflict with
- each other; it is the intent that a single implementation can conform
- to all of them.
-
- 24 Each section is divided into clauses and subclauses that have a common
- structure. Each section, clause, and subclause first introduces its subject.
- After the introductory text, text is labeled with the following headings:
-
-
- Language Design Principles
-
- 24.a These are not rules of the language, but guiding principles or
- goals used in defining the rules of the language. In some cases, the
- goal is only partially met; such cases are explained.
-
- 24.b This is not part of the definition of the language, and does
- not appear in the RM9X.
- Syntax
-
- 25 {syntax (under Syntax heading)} {grammar (under Syntax heading)}
- {context free grammar (under Syntax heading)} {BNF (Backus-Naur Form)
- (under Syntax heading)} {Backus-Naur Form (BNF) (under Syntax heading)}
- Syntax rules (indented).
-
-
- Name Resolution Rules
-
- 26 {name resolution rules} {overloading rules} {resolution rules}
- Compile-time rules that are used in name resolution, including overload
- resolution.
-
- 26.a Discussion: These rules are observed at compile time. (We
- say ``observed'' rather than ``checked,'' because these rules are not
- individually checked. They are really just part of the Legality
- Rules in Section 8 that require exactly one interpretation of each
- constituent of a complete context.) The only rules used in overload
- resolution are the Syntax Rules and the Name Resolution Rules.
-
- 26.b When dealing with non-overloadable declarations it sometimes
- makes no semantic difference whether a given rule is a Name
- Resolution Rule or a Legality Rule, and it is sometimes difficult to
- decide which it should be. We generally make a given rule a Name
- Resolution Rule only if it has to be. For example, ``The name, if
- any, in a raise_statement shall be the name of an exception.'' is
- under ``Legality Rules.''
-
-
- Legality Rules
-
- 27 {legality rules} {compile-time error} {error (compile-time)} Rules that
- are enforced at compile time. {legal (construct)} {illegal (construct)} A
- construct is legal if it obeys all of the Legality Rules.
-
- 27.a Discussion: These rules are not used in overload resolution.
-
- 27.b Note that run-time errors are always attached to exceptions;
- for example, it is not ``illegal'' to divide by zero, it just raises
- an exception.
-
-
- Static Semantics
-
- 28 {static semantics} {compile-time semantics} A definition of the
- compile-time effect of each construct.
-
- 28.a Discussion: The most important compile-time effects represent
- the effects on the symbol table associated with declarations
- (implicit or explicit). In addition, we use this heading as a bit of
- a grab bag for equivalences, package specifications, etc. For
- example, this is where we put statements like so-and-so is equivalent
- to such-and-such. (We ought to try to really mean it when we say
- such things!) Similarly, statements about magically-generated
- implicit declarations go here. These rules are generally written as
- statements of fact about the semantics, rather than as a
- you-shall-do-such-and-such sort of thing.
-
-
- Post-Compilation Rules
-
- 29 {post-compilation rules} {post-compilation error} {post-compilation
- rules} {link-time error: see post-compilation error} {error (link-time)}
- Rules that are enforced before running a partition. {legal (partition)}
- {illegal (partition)} A partition is legal if its compilation units are legal
- and it obeys all of the Post-Compilation Rules.
-
- 29.a Discussion: It is not specified exactly when these rules are
- checked, so long as they are checked for any given partition before
- that partition starts running. An implementation may choose to check
- some such rules at compile time, and reject compilation_units
- accordingly. Alternatively, an implementation may check such rules
- when the partition is created (usually known as ``link time''), or
- when the partition is mapped to a particular piece of hardware (but
- before the partition starts running).
-
-
- Dynamic Semantics
-
- 30 {dynamic semantics} {run-time semantics} {run-time error} {error
- (run-time)} A definition of the run-time effect of each construct.
-
- 30.a Discussion: This heading describes what happens at run time.
- Run-time checks, which raise exceptions upon failure, are described
- here. Each item that involves a run-time check is marked with the
- name of the check -- these are the same check names that are used in
- a pragma Suppress. Principle: Every check should have a name, usable
- in a pragma Suppress.
-
-
- Bounded (Run-Time) Errors
-
- 31 {bounded error} {bounded error} Situations that result in bounded
- (run-time) errors (see 1.1.5).
-
- 31.a Discussion: The ``bounds'' of each such error are described
- here -- that is, we characterize the set of all possible behaviors
- that can result from a bounded error occurring at run time.
-
-
- Erroneous Execution
-
- 32 {erroneous execution} {erroneous execution} Situations that result in
- erroneous execution (see 1.1.5).
-
-
- Implementation Requirements
-
- 33 {implementation requirements} Additional requirements for conforming
- implementations.
-
- 33.a Discussion: ...as opposed to rules imposed on the programmer.
- An example might be, ``The smallest representable duration,
- Duration'Small, shall not be greater than twenty milliseconds.''
-
- 33.b It's really just an issue of how the rule is worded. We could
- write the same rule as ``The smallest representable duration is an
- implementation-defined value less than or equal to 20 milliseconds''
- and then it would be under ``Static Semantics.''
-
-
- Documentation Requirements
-
- 34 {documentation requirements} {documentation requirements} Documentation
- requirements for conforming implementations.
-
- 34.a Discussion: These requirements are beyond those that are
- implicitly specified by the phrase ``implementation defined''. The
- latter require documentation as well, but we don't repeat these cases
- under this heading. Usually this heading is used for when the
- description of the documentation requirement is longer and does not
- correspond directly to one, narrow normative sentence.
-
-
- Metrics
-
- 35 {metrics} {metrics} Metrics that are specified for the time/space
- properties of the execution of certain language constructs.
-
-
- Implementation Permissions
-
- 36 {implementation permissions} Additional permissions given to the
- implementer.
-
- 36.a Discussion: For example, ``The implementation is allowed to
- impose further restrictions on the record aggregates allowed in code
- statements.'' When there are restrictions on the permission, those
- restrictions are given here also. For example, ``An implementation
- is allowed to restrict the kinds of subprograms that are allowed to
- be main subprograms. However, it shall support at least
- parameterless procedures.'' -- we don't split this up between here
- and ``Implementation Requirements.''
-
-
- Implementation Advice
-
- 37 {implementation advice} {advice} Optional advice given to the
- implementer. The word ``should'' is used to indicate that the advice is a
- recommendation, not a requirement. It is implementation defined whether or
- not a given recommendation is obeyed.
-
- 37.a Implementation defined: Whether or not each recommendation
- given in Implementation Advice is followed.
-
- 37.b Discussion: The advice generally shows the intended
- implementation, but the implementer is free to ignore it. The
- implementer is the sole arbiter of whether or not the advice has been
- obeyed, if not, whether the reason is a good one, and whether the
- required documentation is sufficient. {ACVC [Ada Compiler Validation
- Capability]} {Ada Compiler Validation Capability [ACVC]} It would be
- wrong for the ACVC to enforce any of this advice.
-
- 37.c For example, ``Whenever possible, the implementation should
- choose a value no greater than fifty microseconds for the smallest
- representable duration, Duration'Small.''
-
- 37.d We use this heading, for example, when the rule is so low
- level or implementation-oriented as to be untestable. We also use
- this heading when we wish to encourage implementations to behave in a
- certain way in most cases, but we do not wish to burden
- implementations by requiring the behavior.
-
-
- NOTES
- 38 (1) {notes} Notes emphasize consequences of the rules described in the
- (sub)clause or elsewhere. This material is informative.
-
-
- Examples
-
- 39 Examples illustrate the possible forms of the constructs described.
- This material is informative.
-
- 39.a Discussion:
-
-
- The next three headings list all language changes between Ada 83 and
- Ada 9X. Language changes are any change that changes the set of text
- strings that are legal Ada programs, or changes the meaning of any
- legal program. Wording changes, such as changes in terminology, are
- not language changes. Each language change falls into one of the
- following three categories:
-
-
- Inconsistencies With Ada 83
-
- 39.b {inconsistencies with Ada 83} {inconsistencies with Ada 83}
- This heading lists all of the upward inconsistencies between Ada 83
- and Ada 9X. Upward inconsistencies are situations in which a legal
- Ada 83 program is a legal Ada 9X program with different semantics.
- This type of upward incompatibility is the worst type for users, so
- we only tolerate it in rare situations.
-
- 39.c (Note that the semantics of a program is not the same thing as
- the behavior of the program. Because of Ada's indeterminacy, the
- ``semantics'' of a given feature describes a set of behaviors that
- can be exhibited by that feature. The set can contain more than one
- allowed behavior. Thus, when we ask whether the semantics changes,
- we are asking whether the set of behaviors changes.)
-
- 39.d This is not part of the definition of the language, and does
- not appear in the RM9X.
-
- Incompatibilities With Ada 83
-
- 39.e {incompatibilities with Ada 83} {incompatibilities with Ada
- 83} This heading lists all of the upward incompatibilities between
- Ada 83 and Ada 9X, except for the ones listed under ``Inconsistencies
- With Ada 83'' above. These are the situations in which a legal Ada
- 83 program is illegal in Ada 9X. We do not generally consider a
- change that turns erroneous execution into an exception, or into an
- illegality, to be upwardly incompatible.
-
- 39.f This is not part of the definition of the language, and does
- not appear in the RM9X.
-
- Extensions to Ada 83
-
- 39.g {extensions to Ada 83} {extensions to Ada 83} This heading is
- used to list all upward compatible language changes; that is,
- language extensions. These are the situations in which a legal Ada
- 9X program is not a legal Ada 83 program. The vast majority of
- language changes fall into this category.
-
- 39.h This is not part of the definition of the language, and does
- not appear in the RM9X.
-
-
-
- 39.i As explained above, the next heading does not represent any
- language change:
-
- Wording Changes From Ada 83
-
- 39.j {wording changes from Ada 83} This heading lists some of the
- non-semantic changes between RM83 and the RM9X. It is incomplete; we
- have not attempted to list all wording changes, but only the
- ``interesting'' ones.
-
- 39.k This is not part of the definition of the language, and does
- not appear in the RM9X.
-
-
-
- 1.1.3 Conformity of an Implementation with the Standard
-
- Implementation Requirements
-
- 1 {conformance (of an implementation with the Standard)} A conforming
- implementation shall:
-
- 1.a Discussion: {implementation} The implementation is the
- software and hardware that implements the language. This includes
- compiler, linker, operating system, hardware, etc.
-
- 1.b 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.
-
- 2 Translate and correctly execute legal programs written in Ada,
- provided that they are not so large as to exceed the capacity of
- the implementation;
-
- 3 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);
-
- 3.a Implementation defined: Capacity limitations of the
- implementation.
-
- 4 Identify all programs or program units that contain errors whose
- detection is required by this International Standard;
-
- 4.a 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.
-
- 4.b 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.
-
- 4.c See also the Implementation Requirements of 10.2, which disallow
- the execution of illegal partitions. {94-4712.a}
-
- 5 Supply all language-defined library units required by this
- International Standard;
-
- 5.a 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.
-
- 5.b 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.
-
- 5.c {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.
-
- 5.d 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.
-
- 6 Contain no variations except those explicitly permitted by this
- International Standard, or those that are impossible or
- impractical to avoid given the implementation's execution
- environment;
-
- 6.a Implementation defined: Variations from the standard that are
- impractical to avoid given the implementation's execution
- environment.
-
- 6.b 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.
-
- 7 Specify all such variations in the manner prescribed by this
- International Standard. {94-4485.d} {94-4749.a}
-
- 8 {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:
-
- 9 Any interaction with an external file (see A.7);
-
- 10 The execution of certain code_statements (see 13.8); which code_
- statements cause external interactions is implementation defined.
-
- 10.a Implementation defined: Which code_statements cause external
- interactions.
-
- 11 Any call on an imported subprogram (see Annex B), including any
- parameters passed to it;
-
- 12 Any result returned or exception propagated from a main
- subprogram (see 10.2) or an exported subprogram (see Annex B) to
- an external caller;
-
- 12.a Discussion: By ``result returned'' we mean to include function
- results and values returned in [in] out parameters.
-
- 13 [Any read or update of an atomic or volatile object (see C.6);]
-
- 14 The values of imported and exported objects (see Annex B) at the
- time of any other interaction with the external environment.
-
- 14.a To be honest: Also other uses of imported and exported
- entities, as defined by the implementation, if the
- implementation supports such pragmas.
-
- 15 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.
-
- 15.a 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.
-
- 15.b 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.
-
- 15.c 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.
-
- 15.d 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.
-
- 16 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.
-
- 16.a 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.
-
- 17 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.
-
- 17.a 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.
-
- 17.b 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.
-
- 17.c 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
-
- 18 {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.
-
- 18.a 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.
-
- 18.b Note that the ``set of possible effects'' can be ``all
- imaginable effects'', as is the case with erroneous execution.
-
- 19 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.
-
- 19.a 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.
-
- 19.b 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
-
- 20 {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.
-
- 20.a 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.
-
- 21 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.
-
- 21.a 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.
-
-
- NOTES
- 22 (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.
-
- 22.a 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.
-
-
-
- 1.1.4 Method of Description and Syntax Notation
-
- 1 The form of an Ada program is described by means of a context-free syntax
- together with context-dependent requirements expressed by narrative rules.
-
- 2 The meaning of Ada programs is described by means of narrative rules
- defining both the effects of each construct and the composition rules for
- constructs.
-
- 3 {syntax (notation)} {grammar (notation)} {context free grammar
- (notation)} {BNF (Backus-Naur Form) (notation)} {Backus-Naur Form (BNF)
- (notation)} The context-free syntax of the language is described using a
- simple variant of Backus-Naur Form. In particular:
-
- 4 Lower case words in a sans-serif font, some containing embedded
- underlines, are used to denote syntactic categories, for example:
-
- 5 case_statement
-
- 6 Boldface words are used to denote reserved words, for example:
-
- 7 array
-
- 8 Square brackets enclose optional items. Thus the two following
- rules are equivalent.
-
- 9 return_statement ::= return [expression];
- return_statement ::= return; | return expression;
-
- 10 Curly brackets enclose a repeated item. The item may appear zero
- or more times; the repetitions occur from left to right as with
- an equivalent left-recursive rule. Thus the two following rules
- are equivalent.
-
- 11 term ::= factor {multiplying_operator factor}
- term ::= factor | term multiplying_operator factor
-
- 12 A vertical line separates alternative items unless it occurs
- immediately after an opening curly bracket, in which case it
- stands for itself:
-
- 13 constraint ::= scalar_constraint | composite_constraint
- discrete_choice_list ::= discrete_choice {| discrete_choice}
-
- 14 {italics (syntax rules)} If the name of any syntactic category
- starts with an italicized part, it is equivalent to the category
- name without the italicized part. The italicized part is
- intended to convey some semantic information. For example
- subtype_name and task_name are both equivalent to name alone.
-
- 14.a Discussion: {LR(1)} {ambiguous grammar} {grammar (resolution
- of ambiguity)} {grammar (ambiguous)} The grammar given in the RM9X is
- not LR(1). In fact, it is ambiguous; the ambiguities are resolved by
- the overload resolution rules (see 8.6).
-
- 14.b We often use ``if'' to mean ``if and only if'' in definitions.
- For example, if we define ``photogenic'' by saying, ``A type is
- photogenic if it has the following properties...,'' we mean that a
- type is photogenic if and only if it has those properties. It is
- usually clear from the context, and adding the ``and only if'' seems
- too cumbersome.
-
- 14.c When we say, for example, ``a declarative_item of a
- declarative_part'', we are talking about a declarative_item
- immediately within that declarative_part. When we say ``a
- declarative_item in, or within, a declarative_part'', we are talking
- about a declarative_item anywhere in the declarative_part, possibly
- deeply nested within other declarative_parts. (This notation doesn't
- work very well for names, since the name ``of'' something also has
- another meaning.)
-
- 14.d When we refer to the name of a language-defined entity (for
- example, Duration), we mean the language-defined entity even in
- programs where the declaration of the language-defined entity is
- hidden by another declaration. For example, when we say that the
- expected type for the expression of a delay_relative_statement is
- Duration, we mean the language-defined type Duration that is declared
- in Standard, not some type Duration the user might have declared.
-
- 15 {syntactic category} A syntactic category is a nonterminal in the
- grammar defined in BNF under ``Syntax.'' Names of syntactic categories are
- set in a different font, like_this.
-
- 16 {Construct} [glossary entry]A construct is a piece of text (explicit or
- implicit) that is an instance of a syntactic category defined under
- ``Syntax.''
-
- 16.a Ramification: For example, an expression is a construct. A
- declaration is a construct, whereas the thing declared by a
- declaration is an ``entity.''
-
- 16.b Discussion: ``Explicit'' and ``implicit'' don't mean exactly
- what you might think they mean: The text of an instance of a generic
- is considered explicit, even though it does not appear explicitly (in
- the non-technical sense) in the program text, and even though its
- meaning is not defined entirely in terms of that text.
-
- 17 {constituent (of a construct)} A constituent of a construct is the
- construct itself, or any construct appearing within it.
-
- 18 {arbitrary order} Whenever the run-time semantics defines certain
- actions to happen in an arbitrary order, this means that the implementation
- shall arrange for these actions to occur in a way that is equivalent to some
- sequential order, following the rules that result from that sequential order.
- When evaluations are defined to happen in an arbitrary order, with conversion
- of the results to some subtypes, or with some run-time checks, the
- evaluations, conversions, and checks may be arbitrarily interspersed, so long
- as each expression is evaluated before converting or checking its value.
- {type conversion [arbitrary order]} {conversion [arbitrary order]} [Note that
- the effect of a program can depend on the order chosen by the implementation.
- This can happen, for example, if two actual parameters of a given call have
- side effects.]
-
- 18.a Discussion: Programs will be more portable if their external
- effect does not depend on the particular order chosen by an
- implementation.
-
- 18.b Ramification: Additional reordering permissions are given in
- 11.6, ``Exceptions and Optimization''.
-
- 18.c There is no requirement that the implementation always choose
- the same order in a given kind of situation. In fact, the
- implementation is allowed to choose a different order for two
- different executions of the same construct. However, we expect most
- implementations will behave in a relatively predictable manner in
- most situations.
-
- 18.d Reason: The ``sequential order'' wording is intended to allow
- the programmer to rely on ``benign'' side effects. For example, if F
- is a function that returns a unique integer by incrementing some
- global and returning the result, a call such as P(F, F) is OK if the
- programmer cares only that the two results of F are unique; the two
- calls of F cannot be executed in parallel, unless the compiler can
- prove that parallel execution is equivalent to some sequential order.
-
-
- NOTES
- 19 (3) The syntax rules describing structured constructs are presented in a
- form that corresponds to the recommended paragraphing. For example, an
- if_statement is defined as:
-
- 20 if_statement ::=
- if condition then
- sequence_of_statements
- {elsif condition then
- sequence_of_statements}
- [else
- sequence_of_statements]
- end if;
-
- 21 (4) The line breaks and indentation in the syntax rules indicate the
- recommended line breaks and indentation in the corresponding constructs.
- The preferred places for other line breaks are after semicolons.
-
-
-
- 1.1.5 Classification of Errors
-
- Implementation Requirements
-
- 1 The language definition classifies errors into several different
- categories:
-
- 2 Errors that are required to be detected prior to run time by
- every Ada implementation;
-
- 3 These errors correspond to any violation of a rule given in
- this International Standard, other than those listed below. In
- particular, violation of any rule that uses the terms shall,
- allowed, permitted, legal, or illegal belongs to this category.
- Any program that contains such an error is not a legal Ada
- program; on the other hand, the fact that a program is legal does
- not mean, per se, that the program is free from other forms of
- error.
-
- 4 {compile-time error} {error (compile-time)} {link-time error:
- see post-compilation error} {error (link-time)} The rules are
- further classified as either compile time rules, or post
- compilation rules, depending on whether a violation has to be
- detected at the time a compilation unit is submitted to the
- compiler, or may be postponed until the time a compilation unit
- is incorporated into a partition of a program.
-
- 4.a Ramification: See, for example, 10.1.3, ``Subunits of
- Compilation Units'', for some errors that are detected only
- after compilation. Implementations are allowed, but not
- required, to detect post compilation rules at compile time when
- possible.
-
- 5 Errors that are required to be detected at run time by the
- execution of an Ada program;
-
- 6 {run-time error} {error (run-time)} The corresponding error
- situations are associated with the names of the predefined
- exceptions. Every Ada compiler is required to generate code that
- raises the corresponding exception if such an error situation
- arises during program execution. [If such an error situation is
- certain to arise in every execution of a construct, then an
- implementation is allowed (although not required) to report this
- fact at compilation time.] {94-4776.a}
-
- 7 Bounded errors;
-
- 8 The language rules define certain kinds of errors that need
- not be detected either prior to or during run time, but if not
- detected, the range of possible effects shall be bounded.
- {bounded error} The errors of this category are called bounded
- errors. {Program_Error (raised by failure of run-time check)}
- The possible effects of a given bounded error are specified for
- each such error, but in any case one possible effect of a bounded
- error is the raising of the exception Program_Error.
-
- 9 Erroneous execution.
-
- 10 {erroneous execution} In addition to bounded errors, the
- language rules define certain kinds of errors as leading to
- erroneous execution. Like bounded errors, the implementation
- need not detect such errors either prior to or during run time.
- Unlike bounded errors, there is no language-specified bound on
- the possible effect of erroneous execution; the effect is in
- general not predictable.
-
- 10.a Ramification: Executions are erroneous, not programs or
- parts of programs. Once something erroneous happens, the
- execution of the entire program is erroneous from that point on,
- and potentially before given possible reorderings permitted by
- 11.6 and elsewhere. We cannot limit it to just one partition,
- since partitions are not required to live in separate address
- spaces. (But implementations are encouraged to limit it as much
- as possible.)
-
- 10.b Suppose a program contains a pair of things that will be
- executed ``in an arbitrary order.'' It is possible that one
- order will result in something sensible, whereas the other order
- will result in erroneous execution. If the implementation
- happens to choose the first order, then the execution is not
- erroneous. This may seem odd, but it is not harmful.
-
- 10.c Saying that something is erroneous is semantically
- equivalent to saying that the behavior is unspecified. However,
- ``erroneous'' has a slightly more disapproving flavor.
-
-
- Implementation Permissions
-
- 11 [{mode of operation (nonstandard)} {nonstandard mode} An implementation
- may provide nonstandard modes of operation. Typically these modes would be
- selected by a pragma or by a command line switch when the compiler is
- invoked. When operating in a nonstandard mode, the implementation may reject
- compilation_units that do not conform to additional requirements associated
- with the mode, such as an excessive number of warnings or violation of coding
- style guidelines. Similarly, in a nonstandard mode, the implementation may
- apply special optimizations or alternative algorithms that are only
- meaningful for programs that satisfy certain criteria specified by the
- implementation. {mode of operation (standard)} {standard mode} In any case,
- an implementation shall support a standard mode that conforms to the
- requirements of this International Standard; in particular, in the standard
- mode, all legal compilation_units shall be accepted.]
-
- 11.a Discussion: These permissions are designed to authorize
- explicitly the support for alternative modes. Of course, nothing we
- say can prevent them anyway, but this (redundant) paragraph is
- designed to indicate that such alternative modes are in some sense
- ``approved'' and even encouraged where they serve the specialized
- needs of a given user community, so long as the standard mode,
- designed to foster maximum portability, is always available.
-
-
- Implementation Advice
-
- 12 {Program_Error (raised by failure of run-time check)} If an
- implementation detects a bounded error or erroneous execution, it should
- raise Program_Error.
-
-
- Wording Changes From Ada 83
-
- 12.a Some situations that are erroneous in Ada 83 are no longer
- errors at all. For example, depending on the parameter passing
- mechanism when unspecified is possibly non-portable, but not
- erroneous.
-
- 12.b Other situations that are erroneous in Ada 83 are changed to
- be bounded errors. In particular, evaluating an uninitialized scalar
- variable is a bounded error. {Program_Error (raised by failure of
- run-time check)} The possible results are to raise Program_Error (as
- always), or to produce a machine-representable value (which might not
- be in the subtype of the variable). {Constraint_Error (raised by
- failure of run-time check)} Violating a Range_Check or Overflow_Check
- raises Constraint_Error, even if the value came from an uninitialized
- variable. This means that optimizers can no longer ``assume'' that
- all variables are initialized within their subtype's range.
- Violating a check that is suppressed remains erroneous.
-
- 12.c The ``incorrect order dependences'' category of errors is
- removed. All such situations are simply considered potential
- non-portabilities. This category was removed due to the difficulty
- of defining what it means for two executions to have a ``different
- effect.'' For example, if a function with a side-effect is called
- twice in a single expression, it is not in principle possible for the
- compiler to decide whether the correctness of the resulting program
- depends on the order of execution of the two function calls. A
- compile time warning might be appropriate, but raising of Program_
- Error at run time would not be.
-
-
-
- 1.2 Normative References
-
- 1 {references} {bibliography} The following standards contain provisions
- which, through reference in this text, constitute provisions of this
- International Standard. At the time of publication, the editions indicated
- were valid. All standards are subject to revision, and parties to agreements
- based on this International Standard are encouraged to investigate the
- possibility of applying the most recent editions of the standards indicated
- below. Members of IEC and ISO maintain registers of currently valid
- International Standards.
-
- 2 {ISO/IEC 646:1991} {646:1991, ISO/IEC standard} {character set standard
- (7-bit)} ISO/IEC 646:1991, Information technology -- ISO 7-bit coded
- character set for information interchange.
-
- 3 {ISO/IEC 1539:1991} {1539:1991, ISO/IEC standard} {FORTRAN standard}
- ISO/IEC 1539:1991, Information technology -- Programming languages --
- FORTRAN.
-
- 4 {ISO 1989:1985} {1989:1985, ISO standard} {COBOL standard} ISO 1989:1985,
- Programming languages -- COBOL.
-
- 5 {ISO/IEC 6429:1992} {6429:1992, ISO/IEC standard} {character set standard
- (control functions)} ISO/IEC 6429:1992, Information technology -- Control
- functions for coded graphic character sets.
-
- 6 {ISO/IEC 8859-1:1987} {8859-1:1987, ISO/IEC standard} {character set
- standard (8-bit)} ISO/IEC 8859-1:1987, Information processing -- 8-bit
- single-byte coded character sets -- Part 1: Latin alphabet No. 1.
-
- 7 {ISO/IEC 9899:1990} {9899:1990, ISO/IEC standard} {C standard} ISO/IEC
- 9899:1990, Programming languages -- C.
-
- 8 {ISO/IEC 10646-1:1993} {10646-1:1993, ISO/IEC standard} {character set
- standard (16-bit)} ISO/IEC 10646-1:1993, Information technology -- Universal
- Multiple-Octet Coded Character Set (UCS) -- Part 1: Architecture and Basic
- Multilingual Plane. {94-4485.f}
-
- 8.a Discussion: {POSIX} POSIX, Portable Operating System Interface
- (POSIX) -- Part 1: System Application Program Interface (API) [C
- Language], The Institute of Electrical and Electronics Engineers,
- 1990.
-
-
-
- 1.3 Definitions
-
- 1 {italics (terms introduced or defined)} Terms are defined throughout this
- International Standard, indicated by italic type. Terms explicitly defined
- in this International Standard are not to be presumed to refer implicitly to
- similar terms defined elsewhere. Terms not defined in this International
- Standard are to be interpreted according to the Webster's Third New
- International Dictionary of the English Language. Informal descriptions of
- some terms are also given in Annex N, ``Glossary''.
-
- 1.a Discussion: The index contains an entry for every defined
- term.
-
- 1.b Glossary entry: Each term defined in Annex N is marked like
- this.
-
-
- 1.c Discussion: Here are some AARM-only definitions: {Ada
- Rapporteur Group (ARG)} {ARG} The Ada Rapporteur Group (ARG)
- interprets the RM83. {Ada Issue (AI)} {AI} An Ada Issue (AI) is a
- numbered ruling from the ARG. {Ada Commentary Integration Document
- (ACID)} {ACID} The Ada Commentary Integration Document (ACID) is an
- edition of RM83 in which clearly marked insertions and deletions
- indicate the effect of integrating the approved AIs. {Uniformity
- Rapporteur Group (URG)} {URG} The Uniformity Rapporteur Group (URG)
- issues recommendations intended to increase uniformity across Ada
- implementations. {Uniformity Issue (UI)} {UI} A Uniformity Issue
- (UI) is a numbered recommendation from the URG.
-
-
-
- Section 2: Lexical Elements
-
-
- 1 [The text of a program consists of the texts of one or more compilations.
- The text of a compilation is a sequence of lexical elements, each composed of
- characters; the rules of composition are given in this section. Pragmas,
- which provide certain information for the compiler, are also described in
- this section.]
-
-
-
- 2.1 Character Set
-
- 1 {character set} The only characters allowed outside of comments are the
- graphic_characters and format_effectors.
-
- 1.a Ramification: Any character, including an other_control_
- function, is allowed in a comment.
-
- 1.b Note that this rule doesn't really have much force, since the
- implementation can represent characters in the source in any way it
- sees fit. For example, an implementation could simply define that
- what seems to be a non-graphic, non-format-effector character is
- actually a representation of the space character.
-
- 1.c Discussion: It is our intent to follow the terminology of ISO
- 10646 BMP where appropriate, and to remain compatible with the
- character classifications defined in A.3, ``Character Handling''.
- Note that our definition for graphic_character is more inclusive than
- that of ISO 10646-1.
- Syntax
-
- 2 character ::= graphic_character | format_effector | other_control_function
-
- 3 graphic_character ::= identifier_letter | digit | space_character | special\
- _character
-
-
- Static Semantics
-
- 4 The character repertoire for the text of an Ada program consists of the
- collection of characters called the Basic Multilingual Plane (BMP) of the ISO
- 10646 Universal Multiple-Octet Coded Character Set, plus a set of format_
- effectors and, in comments only, a set of other_control_functions; the coded
- representation for these characters is implementation defined [(it need not
- be a representation defined within ISO-10646-1)].
-
- 4.a Implementation defined: The coded representation for the text
- of an Ada program.
-
- 5 The description of the language definition in this International Standard
- uses the graphic symbols defined for Row 00: Basic Latin and Row 00: Latin-1
- Supplement of the ISO 10646 BMP; these correspond to the graphic symbols of
- ISO 8859-1 (Latin-1); no graphic symbols are used in this International
- Standard for characters outside of Row 00 of the BMP. The actual set of
- graphic symbols used by an implementation for the visual representation of
- the text of an Ada program is not specified. {unspecified [partial]}
-
- 6 The categories of characters are defined as follows:
-
- 7 {identifier_letter} identifier_letter
- upper_case_identifier_letter | lower_case_identifier_letter
-
- 7.a Discussion: We use identifier_letter instead of simply letter
- because ISO 10646 BMP includes many other characters that would
- generally be considered "letters."
-
- 8 {upper_case_identifier_letter} upper_case_identifier_letter
- Any character of Row 00 of ISO 10646 BMP whose name begins
- ``Latin Capital Letter''.
-
- 9 {lower_case_identifier_letter} lower_case_identifier_letter
- Any character of Row 00 of ISO 10646 BMP whose name begins
- ``Latin Small Letter''.
-
- 10 {digit} digit
- One of the characters 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9.
-
- 11 {space_character} space_character
- The character of ISO 10646 BMP named ``Space''.
-
- 12 {special_character} special_character
- Any character of the ISO 10646 BMP that is not reserved for a
- control function, and is not the space_character, an
- identifier_letter, or a digit.
-
- 12.a Ramification: Note that the no break space and soft hyphen are
- special_characters, and therefore graphic_characters. They are not
- the same characters as space and hyphen-minus.
-
- 13 {format_effector} format_effector
- The control functions of ISO 6429 called character tabulation
- (HT), line tabulation (VT), carriage return (CR), line feed
- (LF), and form feed (FF). {control character: see also
- format_effector}
-
- 14 {other_control_function} other_control_function
- Any control function, other than a format_effector, that is
- allowed in a comment; the set of other_control_functions
- allowed in comments is implementation defined.
-
- 14.a Implementation defined: The control functions allowed in comments.
-
- {control character: see also other_control_function}
-
- 15 {names of special_characters} {special_character (names)} The following
- names are used when referring to certain special_characters: {quotation
- mark} {number sign} {ampersand} {apostrophe} {tick} {left parenthesis} {right
- parenthesis} {asterisk} {multiply} {plus sign} {comma} {hyphen-minus} {minus}
- {full stop} {dot} {point} {solidus} {divide} {colon} {semicolon} {less-than
- sign} {equals sign} {greater-than sign} {low line} {underline} {vertical
- line} {left square bracket} {right square bracket} {left curly bracket}
- {right curly bracket}
-
- 15.a Discussion: These are the ones that play a special role in
- the syntax of Ada 9X, or in the syntax rules; we don't bother to
- define names for all characters. The first name given is the name
- from ISO 10646-1; the subsequent names, if any, are those used within
- the standard, depending on context.
-
- symbol name symbol name
-
- " quotation mark : colon
- # number sign ; semicolon
- & ampersand < less-than sign
- ' apostrophe, tick = equals sign
- ( left parenthesis > greater-than sign
- ) right parenthesis _ low line, underline
- * asterisk, multiply | vertical line
- + plus sign [ left square bracket
- , comma ] right square bracket
- - hyphen-minus, minus { left curly bracket
- . full stop, dot, point } right curly bracket
- / solidus, divide
-
-
-
- Implementation Permissions
-
- 16 In a nonstandard mode, the implementation may support a different
- character repertoire[; in particular, the set of characters that are
- considered identifier_letters can be extended or changed to conform to local
- conventions].
-
- 16.a Ramification: If an implementation supports other character
- sets, it defines which characters fall into each category, such as
- ``identifier_letter,'' and what the corresponding rules of this
- section are, such as which characters are allowed in the text of a
- program.
-
-
- NOTES
- 17 (1) Every code position of ISO 10646 BMP that is not reserved for a
- control function is defined to be a graphic_character by this
- International Standard. This includes all code positions other than
- 0000 - 001F, 007F - 009F, and FFFE - FFFF.
-
- 18 (2) The language does not specify the source representation of programs.
-
- 18.a Discussion: Any source representation is valid so long as the
- implementer can produce an (information-preserving) algorithm for
- translating both directions between the representation and the
- standard character set. (For example, every character in the
- standard character set has to be representable, even if the output
- devices attached to a given computer cannot print all of those
- characters properly.) From a practical point of view, every
- implementer will have to provide some way to process the ACVC. It is
- the intent to allow source representations, such as parse trees, that
- are not even linear sequences of characters. It is also the intent
- to allow different fonts: reserved words might be in bold face, and
- that should be irrelevant to the semantics.
-
-
- Extensions to Ada 83
-
- 18.b {extensions to Ada 83} Ada 9X allows 8-bit and 16-bit
- characters, as well as implementation-specified character sets.
-
- Wording Changes From Ada 83
-
- 18.c The syntax rules in this clause are modified to remove the
- emphasis on basic characters vs. others. (In this day and age, there
- is no need to point out that you can write programs without using
- (for example) lower case letters.) In particular, character
- (representing all characters usable outside comments) is added, and
- basic_graphic_character, other_special_character, and basic_character
- are removed. Special_character is expanded to include Ada 83's
- other_special_character, as well as new 8-bit characters not present
- in Ada 83. Note that the term ``basic letter'' is used in A.3,
- ``Character Handling'' to refer to letters without diacritical marks.
-
- 18.d Character names now come from ISO 10646.
-
- 18.e We use identifier_letter rather than letter since ISO 10646
- BMP includes many "letters' that are not permitted in identifiers (in
- the standard mode).
-
-
-
- 2.2 Lexical Elements, Separators, and Delimiters
-
- Static Semantics
-
- 1 {text of a program} The text of a program consists of the texts of one or
- more compilations. {lexical element} {token: see lexical element} The text
- of each compilation is a sequence of separate lexical elements. Each lexical
- element is formed from a sequence of characters, and is either a delimiter,
- an identifier, a reserved word, a numeric_literal, a character_literal, a
- string_literal, or a comment. The meaning of a program depends only on the
- particular sequences of lexical elements that form its compilations,
- excluding comments.
-
- 2 The text of a compilation is divided into {line} lines. {end of a line}
- In general, the representation for an end of line is implementation defined.
-
- 2.a Implementation defined: The representation for an end of line.
-
- However, a sequence of one or more format_effectors other than character
- tabulation (HT) signifies at least one end of line.
-
- 3 {separator} [In some cases an explicit separator is required to separate
- adjacent lexical elements.] A separator is any of a space character, a
- format effector, or the end of a line, as follows:
-
- 3.a Discussion: It might be useful to define ``white space'' and
- use it here.
-
- 4 A space character is a separator except within a comment, a
- string_literal, or a character_literal.
-
- 5 Character tabulation (HT) is a separator except within a comment.
-
- 6 The end of a line is always a separator.
-
- 7 One or more separators are allowed between any two adjacent lexical
- elements, before the first of each compilation, or after the last. At least
- one separator is required between an identifier, a reserved word, or a
- numeric_literal and an adjacent identifier, reserved word, or numeric_
- literal.
-
- 8 {delimiter} A delimiter is either one of the following special characters
-
- 9 & ' ( ) * + , - . / : ; < = > |
-
- 10 {compound delimiter} or one of the following compound delimiters each
- composed of two adjacent special characters
-
- 11 => .. ** := /= >= <= << >> <>
-
- 12 Each of the special characters listed for single character delimiters is
- a single delimiter except if this character is used as a character of a
- compound delimiter, or as a character of a comment, string_literal,
- character_literal, or numeric_literal.
-
- 13 The following names are used when referring to compound delimiters:
-
- 14 delimiter name
-
- => arrow
- .. double dot
- ** double star, exponentiate
- := assignment (pronounced: ``becomes'')
- /= inequality (pronounced: ``not equal'')
- >= greater than or equal
- <= less than or equal
- << left label bracket
- >> right label bracket
- <> box
-
-
- Implementation Requirements
-
- 15 An implementation shall support lines of at least 200 characters in
- length, not counting any characters used to signify the end of a line. An
- implementation shall support lexical elements of at least 200 characters in
- length. The maximum supported line length and lexical element length are
- implementation defined.
-
- 15.a Implementation defined: Maximum supported line length and
- lexical element length.
-
- 15.b Discussion: From URG recommendation.
-
-
-
- 2.3 Identifiers
-
- 1 Identifiers are used as names.
-
-
- Syntax
-
- 2 identifier ::=
- identifier_letter {[underline] letter_or_digit}
-
- 3 letter_or_digit ::= identifier_letter | digit
-
- 4 An identifier shall not be a reserved word.
-
-
- Static Semantics
-
- 5 All characters of an identifier are significant, including any underline
- character. {case insensitive} Identifiers differing only in the use of
- corresponding upper and lower case letters are considered the same.
-
- 5.a Discussion: Two of the letters of ISO 8859-1 appear only as
- lower case, "sharp s" and "y with diaeresis." These two letters have
- no corresponding upper case letter (in particular, they are not
- considered equivalent to one another).
-
-
- Implementation Permissions
-
- 6 In a nonstandard mode, an implementation may support other upper/lower
- case equivalence rules for identifiers[, to accommodate local conventions].
-
-
- Examples
-
- 7 Examples of identifiers:
-
- 8 Count X Get_Symbol Ethelyn Marion
-
- Snobol_4 X1 Page_Count Store_Next_Item
-
-
- Wording Changes From Ada 83
-
- 8.a We no longer include reserved words as identifiers. This is
- not a language change. In Ada 83, identifier included reserved
- words. However, this complicated several other rules (for example,
- regarding implementation-defined attributes and pragmas, etc.). We
- now explicitly allow certain reserved words for attribute
- designators, to make up for the loss.
-
- 8.b Ramification: Because syntax rules are relevant to overload
- resolution, it means that if it looks like a reserved word, it is not
- an identifier. As a side effect, implementations cannot use reserved
- words as implementation-defined attributes or pragma names.
-
-
-
- 2.4 Numeric Literals
-
- 1 {literal (numeric)} There are two kinds of numeric_literals, real
- literals and integer literals. {real literal} A real literal is a numeric_
- literal that includes a point; {integer literal} an integer literal is a
- numeric_literal without a point.
-
-
- Syntax
-
- 2 numeric_literal ::= decimal_literal | based_literal
-
-
- NOTES
- 3 (3) The type of an integer literal is universal_integer. The type of a
- real literal is universal_real.
-
-
-
- 2.4.1 Decimal Literals
-
- 1 {literal (decimal)} A decimal_literal is a numeric_literal in the
- conventional decimal notation (that is, the base is ten).
-
-
- Syntax
-
- 2 decimal_literal ::= numeral [.numeral] [exponent]
-
- 3 numeral ::= digit {[underline] digit}
-
- 4 exponent ::= E [+] numeral | E - numeral
-
- 5 An exponent for an integer literal shall not have a minus sign.
-
- 5.a Ramification: Although this rule is in this subclause, it
- applies also to the next subclause.
-
-
- Static Semantics
-
- 6 An underline character in a numeric_literal does not affect its meaning.
- The letter E of an exponent can be written either in lower case or in upper
- case, with the same meaning.
-
- 6.a Ramification: Although these rules are in this subclause, they
- apply also to the next subclause.
-
- 7 An exponent indicates the power of ten by which the value of the decimal_
- literal without the exponent is to be multiplied to obtain the value of the
- decimal_literal with the exponent.
-
-
- Examples
-
- 8 Examples of decimal literals:
-
- 9
- 12 0 1E6 123_456 -- integer literals
-
- 12.0 0.0 0.456 3.14159_26 -- real literals
-
-
- Wording Changes From Ada 83
-
- 9.a We have changed the syntactic category name integer to be
- numeral. We got this idea from ACID. It avoids the confusion
- between this and integers. (Other places don't offer similar
- confusions. For example, a string_literal is different from a
- string.)
-
-
-
- 2.4.2 Based Literals
-
- 1 [{literal (based)} {binary literal} {base 2 literal} {binary (literal)}
- {octal literal} {base 8 literal} {octal (literal)} {hexadecimal literal}
- {base 16 literal} {hexadecimal (literal)} A based_literal is a numeric_
- literal expressed in a form that specifies the base explicitly.]
-
-
- Syntax
-
- 2 based_literal ::=
- base # based_numeral [.based_numeral] # [exponent]
- 3 base ::= numeral
-
- 4 based_numeral ::=
- extended_digit {[underline] extended_digit}
-
- 5 extended_digit ::= digit | A | B | C | D | E | F
-
-
- Legality Rules
-
- 6 {base} The base (the numeric value of the decimal numeral preceding the
- first #) shall be at least two and at most sixteen. The extended_digits A
- through F represent the digits ten through fifteen, respectively. The value
- of each extended_digit of a based_literal shall be less than the base.
-
-
- Static Semantics
-
- 7 The conventional meaning of based notation is assumed. An exponent
- indicates the power of the base by which the value of the based_literal
- without the exponent is to be multiplied to obtain the value of the based_
- literal with the exponent. The base and the exponent, if any, are in decimal
- notation.
-
- 8 The extended_digits A through F can be written either in lower case or in
- upper case, with the same meaning.
-
-
- Examples
-
- 9 Examples of based literals:
-
- 10
- 2#1111_1111# 16#FF# 016#0ff# -- integer literal\
- s of value 255
- 16#E#E1 2#1110_0000# -- integer literal\
- s of value 224
- 16#F.FF#E+2 2#1.1111_1111_1110#E11 -- real literals o\
- f value 4095.0
-
-
- Wording Changes From Ada 83
-
- 10.a The rule about which letters are allowed is now encoded in
- BNF, as suggested by Mike Woodger. This is clearly more readable.
-
-
-
- 2.5 Character Literals
-
- 1 [A character_literal is formed by enclosing a graphic character between
- two apostrophe characters.]
-
-
- Syntax
-
- 2 character_literal ::= 'graphic_character'
-
-
- NOTES
- 3 (4) A character_literal is an enumeration literal of a character type.
- See 3.5.2.
-
-
- Examples
-
- 4 Examples of character literals:
-
- 5 'A' '*' ''' ' '
-
-
- Wording Changes From Ada 83
-
- 5.a The definitions of the values of literals are in Sections 3 and
- 4, rather than here, since it requires knowledge of types.
-
-
-
- 2.6 String Literals
-
- 1 [A string_literal is formed by a sequence of graphic characters (possibly
- none) enclosed between two quotation marks used as string brackets. They are
- used to represent operator_symbols (see 6.1), values of a string type (see
- 4.2), and array subaggregates (see 4.3.3). {quoted string: see string_
- literal}]
-
-
- Syntax
-
- 2 string_literal ::= "{string_element}"
-
- 3 string_element ::= "" | non_quotation_mark_graphic_character
-
- 4 A string_element is either a pair of quotation marks (""), or a
- single graphic_character other than a quotation mark.
-
-
- Static Semantics
-
- 5 {sequence of characters (of a string_literal)} The sequence of characters
- of a string_literal is formed from the sequence of string_elements between
- the bracketing quotation marks, in the given order, with a string_element
- that is "" becoming a single quotation mark in the sequence of characters,
- and any other string_element being reproduced in the sequence.
-
- 6 {null string literal} A null string literal is a string_literal with no
- string_elements between the quotation marks.
-
-
- NOTES
- 7 (5) An end of line cannot appear in a string_literal.
-
-
- Examples
-
- 8 Examples of string literals:
-
- 9
- "Message of the day:"
-
- "" -- a null string literal
- " " "A" """" -- three string literals of length 1
-
- "Characters such as $, %, and } are allowed in string literals"
-
-
- Wording Changes From Ada 83
-
- 9.a The wording has been changed to be strictly lexical. No
- mention is made of string or character values, since string_literals
- are also used to represent operator_symbols, which don't have a
- defined value.
-
- 9.b The syntax is described differently.
-
-
-
- 2.7 Comments
-
- 1 A comment starts with two adjacent hyphens and extends up to the end of
- the line.
-
-
- Syntax
-
- 2 comment ::= --{non_end_of_line_character}
-
- 3 A comment may appear on any line of a program.
-
-
- Static Semantics
-
- 4 The presence or absence of comments has no influence on whether a program
- is legal or illegal. Furthermore, comments do not influence the meaning of a
- program; their sole purpose is the enlightenment of the human reader.
-
-
- Examples
-
- 5 Examples of comments:
-
- 6 -- the last sentence above echoes the Algol 68 report
-
- end; -- processing of Line is complete
-
- -- a long comment may be split onto
- -- two or more consecutive lines
-
- ---------------- the first two hyphens start the comment
-
-
-
- 2.8 Pragmas
-
- 1 {Pragma} [glossary entry]A pragma is a compiler directive. There are
- language-defined pragmas that give instructions for optimization, listing
- control, etc. An implementation may support additional (implementation-
- defined) pragmas.
-
-
- Syntax
-
- 2 pragma ::=
- pragma identifier [(pragma_argument_association {, pragma_argument_assoc\
- iation})];
-
- 3 pragma_argument_association ::=
- [pragma_argument_identifier =>] name
- | [pragma_argument_identifier =>] expression
-
- 4 In a pragma, any pragma_argument_associations without a pragma_
- argument_identifier shall precede any associations with a pragma_
- argument_identifier.
-
- 5 Pragmas are only allowed at the following places in a program:
-
- 6 After a semicolon delimiter, but not within a formal_part or
- discriminant_part.
-
- 7 At any place where the syntax rules allow a construct defined
- by a syntactic category whose name ends with "declaration",
- "statement", "clause", or "alternative", or one of the
- syntactic categories variant or exception_handler; but not in
- place of such a construct. Also at any place where a
- compilation_unit would be allowed.
-
- 8 Additional syntax rules and placement restrictions exist for specific
- pragmas.
-
-
- 8.a Discussion: The above rule is written in text, rather than in
- BNF; the syntactic category pragma is not used in any BNF syntax
- rule.
-
- 8.b Ramification: A pragma is allowed where a generic_formal_
- parameter_declaration is allowed.
-
-
- 9 {name (of a pragma)} {pragma name} The name of a pragma is the identifier
- following the reserved word pragma. {pragma argument} {argument of a pragma}
- The name or expression of a pragma_argument_association is a pragma argument.
-
- 10 {identifier specific to a pragma} {pragma, identifier specific to} An
- identifier specific to a pragma is an identifier that is used in a pragma
- argument with special meaning for that pragma.
-
- 10.a To be honest: Whenever the syntax rules for a given pragma
- allow "identifier" as an argument of the pragma, that identifier is
- an identifier specific to that pragma.
-
-
- Static Semantics
-
- 11 If an implementation does not recognize the name of a pragma, then it
- has no effect on the semantics of the program. Inside such a pragma, the
- only rules that apply are the Syntax Rules.
-
- 11.a To be honest: This rule takes precedence over any other rules
- that imply otherwise.
-
- 11.b Ramification: Note well: this rule applies only to pragmas
- whose name is not recognized. If anything else is wrong with a
- pragma (at compile time), the pragma is illegal. This is true
- whether the pragma is language defined or implementation defined.
-
- 11.c For example, an expression in an unrecognized pragma does not
- cause freezing, even though the rules in 13.14, ``Freezing Rules''
- say it does; the above rule overrules those other rules. On the
- other hand, an expression in a recognized pragma causes freezing,
- even if this makes something illegal.
-
- 11.d For another example, an expression that would be ambiguous is
- not illegal if it is inside an unrecognized pragma.
-
- 11.e Note, however, that implementations have to recognize pragma
- Inline(Foo) and freeze things accordingly, even if they choose to
- never do inlining.
-
- 11.f Obviously, the contradiction needs to be resolved one way or
- the other. The reasons for resolving it this way are: The
- implementation is simple -- the compiler can just ignore the pragma
- altogether. The interpretation of constructs appearing inside
- implementation-defined pragmas is implementation defined. For
- example: ``pragma Mumble(X);''. If the current implementation has
- never heard of Mumble, then it doesn't know whether X is a name, an
- expression, or an identifier specific to the pragma Mumble.
-
- 11.g To be honest: The syntax of individual pragmas overrides the
- general syntax for pragma.
-
- 11.h Ramification: Thus, an identifier specific to a pragma is not
- a name, syntactically; if it were, the visibility rules would be
- invoked, which is not what we want.
-
- 11.i This also implies that named associations do not allow one to
- give the arguments in an arbitrary order -- the order given in the
- syntax rule for each individual pragma must be obeyed. However, it
- is generally possible to leave out earlier arguments when later ones
- are given; for example, this is allowed by the syntax rule for pragma
- Import (see B.1, ``Interfacing Pragmas''). As for subprogram calls,
- positional notation precedes named notation.
-
- 11.j Note that Ada 83 had no pragmas for which the order of named
- associations mattered, since there was never more than one argument
- that allowed named associations.
-
- 11.k To be honest: The interpretation of the arguments of
- implementation-defined pragmas is implementation defined. However,
- the syntax rules have to be obeyed.
-
-
- Dynamic Semantics
-
- 12 {execution [pragma]} {elaboration [pragma]} Any pragma that appears at
- the place of an executable construct is executed. Unless otherwise specified
- for a particular pragma, this execution consists of the evaluation of each
- evaluable pragma argument in an arbitrary order.
-
- 12.a Ramification: For a pragma that appears at the place of an
- elaborable construct, execution is elaboration.
-
- 12.b An identifier specific to a pragma is neither a name nor an
- expression -- such identifiers are not evaluated (unless an
- implementation defines them to be evaluated in the case of an
- implementation-defined pragma).
-
- 12.c The ``unless otherwise specified'' part allows us (and
- implementations) to make exceptions, so a pragma can contain an
- expression that is not evaluated. Note that pragmas in type_
- definitions may contain expressions that depend on discriminants.
-
- 12.d When we wish to define a pragma with some run-time effect, we
- usually make sure that it appears in an executable context;
- otherwise, special rules are needed to define the run-time effect and
- when it happens.
-
-
- Implementation Requirements
-
- 13 The implementation shall give a warning message for an unrecognized
- pragma name.
-
- 13.a Ramification: An implementation is also allowed to have modes
- in which a warning message is suppressed, or in which the presence of
- an unrecognized pragma is a compile-time error.
-
-
- Implementation Permissions
-
- 14 An implementation may provide implementation-defined pragmas; the name
- of an implementation-defined pragma shall differ from those of the
- language-defined pragmas.
-
- 14.a Implementation defined: Implementation-defined pragmas.
-
- 14.b Ramification: The semantics of implementation-defined
- pragmas, and any associated rules (such as restrictions on their
- placement or arguments), are, of course, implementation defined.
- Implementation-defined pragmas may have run-time effects.
-
- 15 An implementation may ignore an unrecognized pragma even if it violates
- some of the Syntax Rules, if detecting the syntax error is too complex.
-
- 15.a Reason: Many compilers use extra post-parsing checks to
- enforce the syntax rules, since the Ada syntax rules are not LR(k)
- (for any k). (The grammar is ambiguous, in fact.) This paragraph
- allows them to ignore an unrecognized pragma, without having to
- perform such post-parsing checks.
-
-
- Implementation Advice
-
- 16 Normally, implementation-defined pragmas should have no semantic effect
- for error-free programs; that is, if the implementation-defined pragmas are
- removed from a working program, the program should still be legal, and should
- still have the same semantics.
-
- 16.a Ramification: Note that ``semantics'' is not the same as
- ``effect;'' as explained in 1.1.3, the semantics defines a set of
- possible effects.
-
- 16.b Note that adding a pragma to a program might cause an error
- (either at compile time or at run time). On the other hand, if the
- language-specified semantics for a feature are in part implementation
- defined, it makes sense to support pragmas that control the feature,
- and that have real semantics; thus, this paragraph is merely a
- recommendation.
-
- 17 Normally, an implementation should not define pragmas that can make an
- illegal program legal, except as follows:
-
- 18 A pragma used to complete a declaration, such as a pragma Import;
-
- 19 A pragma used to configure the environment by adding, removing,
- or replacing library_items.
-
- 19.a Ramification: For example, it is OK to support Interface,
- System_Name, Storage_Unit, and Memory_Size pragmas for upward
- compatibility reasons, even though all of these pragmas can make an
- illegal program legal. (The latter three can affect legality in a
- rather subtle way: They affect the value of named numbers in System,
- and can therefore affect the legality in cases where static
- expressions are required.)
-
- 19.b On the other hand, adding implementation-defined pragmas to a
- legal program can make it illegal. For example, a common kind of
- implementation-defined pragma is one that promises some property that
- allows more efficient code to be generated. If the promise is a lie,
- it is best if the user gets an error message.
-
-
- Incompatibilities With Ada 83
-
- 19.c {incompatibilities with Ada 83} In Ada 83, ``bad'' pragmas are
- ignored. In Ada 9X, they are illegal, except in the case where the
- name of the pragma itself is not recognized by the implementation.
-
- Extensions to Ada 83
-
- 19.d {extensions to Ada 83} Implementation-defined pragmas may
- affect the legality of a program.
- Wording Changes From Ada 83
-
- 19.e Implementation-defined pragmas may affect the run-time
- semantics of the program. This was always true in Ada 83 (since it
- was not explicitly forbidden by RM83), but it was not clear, because
- there was no definition of ``executing'' or ``elaborating'' a pragma.
-
- Syntax
-
- 20 The forms of List, Page, and Optimize pragmas are as follows:
-
-
- 21 pragma List(identifier);
-
- 22 pragma Page;
-
- 23 pragma Optimize(identifier);
-
- 24 [Other pragmas are defined throughout this International Standard,
- and are summarized in Annex L.]
-
- 24.a Ramification: The language-defined pragmas are supported by
- every implementation, although ``supporting'' some of them (for
- example, Inline) requires nothing more than checking the arguments,
- since they act only as advice to the implementation.
-
-
- Static Semantics
-
- 25 A pragma List takes one of the identifiers On or Off as the single
- argument. This pragma is allowed anywhere a pragma is allowed. It specifies
- that listing of the compilation is to be continued or suspended until a List
- pragma with the opposite argument is given within the same compilation. The
- pragma itself is always listed if the compiler is producing a listing.
-
- 26 A pragma Page is allowed anywhere a pragma is allowed. It specifies
- that the program text which follows the pragma should start on a new page (if
- the compiler is currently producing a listing).
-
- 27 A pragma Optimize takes one of the identifiers Time, Space, or Off as
- the single argument. This pragma is allowed anywhere a pragma is allowed,
- and it applies until the end of the immediately enclosing declarative region,
- or for a pragma at the place of a compilation_unit, to the end of the
- compilation. {94-4761.d} It gives advice to the implementation as to whether
- time or space is the primary optimization criterion, or that optional
- optimizations should be turned off. [It is implementation defined how this
- advice is followed.]
-
- 27.a Implementation defined: Effect of pragma Optimize.
-
- 27.b Discussion: For example, a compiler might use Time vs. Space
- to control whether generic instantiations are implemented with a
- macro-expansion model, versus a shared-generic-body model.
-
- 27.c We don't define what constitutes an ``optimization'' -- in
- fact, it cannot be formally defined in the context of Ada. One
- compiler might call something an optional optimization, whereas
- another compiler might consider that same thing to be a normal part
- of code generation. Thus, the programmer cannot rely on this pragma
- having any particular portable effect on the generated code. Some
- compilers might even ignore the pragma altogether.
-
-
- Examples
-
- 28 Examples of pragmas:
-
- 29 pragma List(Off); -- turn off listing generation
- pragma Optimize(Off); -- turn off optional optimizations
- pragma Inline(Set_Mask); -- generate code for Set_Mask inline
- pragma Suppress(Range_Check, On => Index); -- turn off range checking on In\
- dex
-
-
- Extensions to Ada 83
-
- 29.a {extensions to Ada 83} The Optimize pragma now allows the
- identifier Off to request that normal optimization be turned off.
-
- 29.b An Optimize pragma may appear anywhere pragmas are allowed.
-
- Wording Changes From Ada 83
-
- 29.c We now describe the pragmas Page, List, and Optimize here, to
- act as examples, and to remove the normative material from Annex L,
- ``Language-Defined Pragmas'', so it can be entirely an informative
- annex.
- 2.9 Reserved Words
-
- Syntax
-
- 1
- 2 {reserved word} The following are the reserved words (ignoring
- upper/lower case distinctions):
-
-
- 2.a Discussion: Reserved words have special meaning in the syntax.
- In addition, certain reserved words are used as attribute names.
-
- 2.b The syntactic category identifier no longer allows reserved
- words. We have added the few reserved words that are legal
- explicitly to the syntax for attribute_reference. Allowing
- identifier to include reserved words has been a source of confusion
- for some users, and differs from the way they are treated in the C
- and Pascal language definitions.
-
-
- abort else new return
- abs elsif not reverse
- abstract end null
- accept entry select
- access exception separate
- aliased exit of subtype
- all or
- and for others tagged
- array function out task
- at terminate
- generic package then
- begin goto pragma type
- body private
- if procedure
- case in protected until
- constant is use
- raise
- declare range when
- delay limited record while
- delta loop rem with
- digits renames
- do mod requeue xor
-
-
- NOTES
- 3 (6) The reserved words appear in lower case boldface in this
- International Standard, except when used in the designator of an
- attribute (see 4.1.4). Lower case boldface is also used for a reserved
- word in a string_literal used as an operator_symbol. This is merely a
- convention -- programs may be written in whatever typeface is desired
- and available. {94-4493.d}
-
-
- Incompatibilities With Ada 83
-
- 3.a {incompatibilities with Ada 83} The following words are not
- reserved in Ada 83, but are reserved in Ada 9X: abstract, aliased,
- protected, requeue, tagged, until.
-
- Wording Changes From Ada 83
-
- 3.b The clause entitled ``Allowed Replacements of Characters'' has
- been moved to Annex J, ``Obsolescent Features''.
-
-
-
- Section 3: Declarations and Types
-
-
- 1 This section describes the types in the language and the rules for
- declaring constants, variables, and named numbers.
-
-
-
- 3.1 Declarations
-
- 1 {entity [partial]} The language defines several kinds of named entities
- that are declared by declarations. {name [partial]} The entity's name is
- defined by the declaration, usually by a defining_identifier, but sometimes
- by a defining_character_literal or defining_operator_symbol.
-
- 2 There are several forms of declaration. A basic_declaration is a form of
- declaration defined as follows.
-
-
- Syntax
-
- 3 basic_declaration ::=
- type_declaration | subtype_declaration
- | object_declaration | number_declaration
- | subprogram_declaration | abstract_subprogram_declaration
- | package_declaration | renaming_declaration
- | exception_declaration | generic_declaration
- | generic_instantiation
-
- 4 defining_identifier ::= identifier
-
-
- Static Semantics
-
- 5 {Declaration} [glossary entry]A declaration is a language construct that
- associates a name with (a view of) an entity. {explicit declaration}
- {implicit declaration} A declaration may appear explicitly in the program
- text (an explicit declaration), or may be supposed to occur at a given place
- in the text as a consequence of the semantics of another construct (an
- implicit declaration).
-
- 5.a Discussion: An implicit declaration generally declares a
- predefined or inherited operation associated with the definition of a
- type. This term is used primarily when allowing explicit
- declarations to override implicit declarations, as part of a type
- declaration.
-
- 6 {declaration} Each of the following is defined to be a declaration: any
- basic_declaration; an enumeration_literal_specification; a discriminant_
- specification; a component_declaration; a loop_parameter_specification; a
- parameter_specification; a subprogram_body; an entry_declaration; an entry_
- index_specification; a choice_parameter_specification; a generic_formal_
- parameter_declaration.
-
- 6.a Discussion: This list (when basic_declaration is expanded out)
- contains all syntactic categories that end in "_declaration" or
- "_specification", except for program unit _specifications. Moreover,
- it contains subprogram_body. A subprogram_body is a declaration,
- whether or not it completes a previous declaration. This is a bit
- strange, subprogram_body is not part of the syntax of basic_
- declaration or library_unit_declaration. A renaming-as-body is
- considered a declaration. An accept_statement is not considered a
- declaration. Completions are sometimes declarations, and sometimes
- not.
-
- 7 {Definition} [glossary entry]{view} All declarations contain a definition
- for a view of an entity. A view consists of an identification of the entity
- (the entity of the view), plus view-specific characteristics that affect the
- use of the entity through that view (such as mode of access to an object,
- formal parameter names and defaults for a subprogram, or visibility to
- components of a type). In most cases, a declaration also contains the
- definition for the entity itself (a renaming_declaration is an example of a
- declaration that does not define a new entity, but instead defines a view of
- an existing entity (see 8.5)).
-
- 7.a Glossary entry: {View} (See Definition.)
-
- 7.b Discussion: Most declarations define a view (of some entity)
- whose view-specific characteristics are unchanging for the life of
- the view. However, subtypes are somewhat unusual in that they
- inherit characteristics from whatever view of their type is currently
- visible. Hence, a subtype is not a view of a type; it is more of an
- indirect reference. By contrast, a private type provides a single,
- unchanging (partial) view of its full type.
-
- 8 {scope [informal definition]} For each declaration, the language rules
- define a certain region of text called the scope of the declaration (see
- 8.2). Most declarations associate an identifier with a declared entity.
- Within its scope, and only there, there are places where it is possible to
- use the identifier to refer to the declaration, the view it defines, and the
- associated entity; these places are defined by the visibility rules (see
- 8.3). {name (of (a view of) an entity)} At such places the identifier is
- said to be a name of the entity (the direct_name or selector_name); {denote
- [informal definition]} the name is said to denote the declaration, the view,
- and the associated entity (see 8.6). {declare} The declaration is said to
- declare the name, the view, and in most cases, the entity itself.
-
- 9 As an alternative to an identifier, an enumeration literal can be
- declared with a character_literal as its name (see 3.5.1), and a function can
- be declared with an operator_symbol as its name (see 6.1).
-
- 10 {defining name} The syntax rules use the terms defining_identifier,
- defining_character_literal, and defining_operator_symbol for the defining
- occurrence of a name; these are collectively called defining names. {usage
- name} The terms direct_name and selector_name are used for usage occurrences
- of identifiers, character_literals, and operator_symbols. These are
- collectively called usage names.
-
- 10.a To be honest: The terms identifier, character_literal, and
- operator_symbol are used directly in contexts where the normal
- visibility rules do not apply (such as the identifier that appears
- after the end of a task_body). Analogous conventions apply to the
- use of designator, which is the collective term for identifier and
- operator_symbol.
-
-
- Dynamic Semantics
-
- 11 {execution [distributed]} The process by which a construct achieves its
- run-time effect is called execution. {elaboration [distributed]} {evaluation
- [distributed]} This process is also called elaboration for declarations and
- evaluation for expressions. One of the terms execution, elaboration, or
- evaluation is defined by this International Standard for each construct that
- has a run-time effect.
-
- 11.a Glossary entry: {Execution} The process by which a construct
- achieves its run-time effect is called execution. {elaboration}
- {evaluation} Execution of a declaration is also called elaboration.
- Execution of an expression is also called evaluation.
-
- 11.b To be honest: The term elaboration is also used for the
- execution of certain constructs that are not declarations, and the
- term evaluation is used for the execution of certain constructs that
- are not expressions. For example, subtype_indications are
- elaborated, and ranges are evaluated.
-
- 11.c For bodies, execution and elaboration are both explicitly
- defined. When we refer specifically to the execution of a body, we
- mean the explicit definition of execution for that kind of body, not
- its elaboration.
-
- 11.d Discussion: Technically, "the execution of a declaration" and
- "the elaboration of a declaration" are synonymous. We use the term
- "elaboration" of a construct when we know the construct is
- elaborable. When we are talking about more arbitrary constructs, we
- use the term "execution". For example, we use the term "erroneous
- execution", to refer to any erroneous execution, including erroneous
- elaboration or evaluation.
-
- 11.e When we explicitly define evaluation or elaboration for a
- construct, we are implicitly defining execution of that construct.
-
- 11.f We also use the term "execution" for things like statements,
- which are executable, but neither elaborable nor evaluable. We
- considered using the term "execution" only for non-elaborable,
- non-evaluable constructs, and defining the term "action" to mean what
- we have defined "execution" to mean. We rejected this idea because
- we thought three terms that mean the same thing was enough -- four
- would be overkill. Thus, the term "action" is used only informally
- in the standard (except where it is defined as part of a larger term,
- such as "protected action").
-
- 11.g To be honest: {elaborable} A construct is elaborable if
- elaboration is defined for it. {evaluable} A construct is evaluable
- if evaluation is defined for it. {executable} A construct is
- executable if execution is defined for it.
-
- 11.h Discussion: Don't confuse ``elaborable'' with
- ``preelaborable'' (defined in 10.2.1).
-
- 11.i Evaluation of an evaluable construct produces a result that is
- either a value, a denotation, or a range. The following are
- evaluable: expression; name prefix; range; entry_list_iterator; and
- possibly discrete_range. The last one is curious -- RM83 uses the
- term ``evaluation of a discrete_range,'' but never defines it. One
- might presume that the evaluation of a discrete_range consists of the
- evaluation of the range or the subtype_indication, depending on what
- it is. But subtype_indications are not evaluated; they are
- elaborated.
-
- 11.j Intuitively, an executable construct is one that has a defined
- run-time effect (which may be null). Since execution includes
- elaboration and evaluation as special cases, all elaborable and all
- evaluable constructs are also executable. Hence, most constructs in
- Ada are executable. An important exception is that the constructs
- inside a generic unit are not executable directly, but rather are
- used as a template for (generally) executable constructs in instances
- of the generic.
-
-
- NOTES
- 12 (1) {declare} At compile time, the declaration of an entity declares the
- entity. {create} At run time, the elaboration of the declaration
- creates the entity.
-
- 12.a Ramification: Syntactic categories for declarations are named
- either entity_declaration (if they include a trailing semicolon) or
- entity_specification (if not).
-
- 12.b {entity} The various kinds of named entities that can be declared
- are as follows: an object (including components and parameters), a
- named number, a type (the name always refers to its first subtype), a
- subtype, a subprogram (including enumeration literals and operators),
- a single entry, an entry family, a package, a protected or task unit
- (which corresponds to either a type or a single object), an
- exception, a generic unit, a label, and the name of a statement.
-
- 12.c Identifiers are also associated with names of pragmas, arguments to
- pragmas, and with attributes, but these are not user-definable.
-
-
- Wording Changes From Ada 83
-
- 12.d The syntax rule for defining_identifier is new. It is used
- for the defining occurrence of an identifier. Usage occurrences use
- the direct_name or selector_name syntactic categories. Each
- occurrence of an identifier (or simple_name), character_literal, or
- operator_symbol in the Ada 83 syntax rules is handled as follows in
- Ada 9X:
-
- 12.e It becomes a defining_identifier, defining_character_
- literal, or defining_operator_symbol (or some syntactic
- category composed of these), to indicate a defining
- occurrence;
-
- 12.f It becomes a direct_name, in usage occurrences where the
- usage is required (in Section 8) to be directly visible;
-
- 12.g It becomes a selector_name, in usage occurrences where
- the usage is required (in Section 8) to be visible but
- not necessarily directly visible;
-
- 12.h It remains an identifier, character_literal, or operator_
- symbol, in cases where the visibility rules do not apply
- (such as the designator that appears after the end of a
- subprogram_body).
-
- 12.i For declarations that come in ``two parts'' (program unit
- declaration plus body, private or incomplete type plus full type,
- deferred constant plus full constant), we consider both to be
- defining occurrences. Thus, for example, the syntax for package_body
- uses defining_identifier after the reserved word body, as opposed to
- direct_name.
-
- 12.j The defining occurrence of a statement name is in its implicit
- declaration, not where it appears in the program text. Considering
- the statement name itself to be the defining occurrence would
- complicate the visibility rules.
-
- 12.k The phrase ``visible by selection'' is not used in Ada 9X. It
- is subsumed by simply ``visible'' and the Name Resolution Rules for
- selector_names.
-
- 12.l (Note that in Ada 9X, a declaration is visible at all places
- where one could have used a selector_name, not just at places where a
- selector_name was actually used. Thus, the places where a
- declaration is directly visible are a subset of the places where it
- is visible. See Section 8 for details.)
-
- 12.m We use the term ``declaration'' to cover _specifications that
- declare (views of) objects, such as parameter_specifications. In Ada
- 83, these are referred to as a ``form of declaration,'' but it is not
- entirely clear that they are considered simply ``declarations.''
-
- 12.n RM83 contains an incomplete definition of "elaborated" in this
- clause: it defines "elaborated" for declarations, declarative_parts,
- declarative_items and compilation_units, but "elaboration" is defined
- elsewhere for various other constructs. To make matters worse, Ada
- 9X has a different set of elaborable constructs. Instead of
- correcting the list, it is more maintainable to refer to the term
- "elaborable," which is defined in a distributed manner.
-
- 12.o RM83 uses the term ``has no other effect'' to describe an
- elaboration that doesn't do anything except change the state from
- not-yet-elaborated to elaborated. This was a confusing wording,
- because the answer to ``other than what?'' was to be found many pages
- away. In Ada 9X, we change this wording to ``has no effect'' (for
- things that truly do nothing at run time), and ``has no effect other
- than to establish that so-and-so can happen without failing the
- Elaboration_Check'' (for things where it matters).
-
- 12.p We make it clearer that the term "execution" covers
- elaboration and evaluation as special cases. This was implied in
- RM83. For example, "erroneous execution" can include any execution,
- and RM83-9.4(3) has, "The task designated by any other task object
- depends on the master whose execution creates the task object;" the
- elaboration of the master's declarative_part is doing the task
- creation.
-
-
-
- 3.2 Types and Subtypes
-
- Static Semantics
-
- 1 {type} {primitive operation [partial]} A type is characterized by a set
- of values, and a set of primitive operations which implement the fundamental
- aspects of its semantics. {object [partial]} An object of a given type is a
- run-time entity that contains (has) a value of the type.
-
- 1.a Glossary entry: {Type} Each object has a type. A type has an
- associated set of values, and a set of primitive operations which
- implement the fundamental aspects of its semantics. Types are
- grouped into classes. The types of a given class share a set of
- primitive operations. {closed under derivation} Classes are closed
- under derivation; that is, if a type is in a class, then all of its
- derivatives are in that class.
-
- 1.b Glossary entry: {Subtype} A subtype is a type together with a
- constraint, which constrains the values of the subtype to satisfy a
- certain condition. The values of a subtype are a subset of the
- values of its type.
-
- 2 {class (of types)} Types are grouped into classes of types, reflecting
- the similarity of their values and primitive operations. {language-defined
- class (of types)} There exist several language-defined classes of types (see
- NOTES below). {elementary type} Elementary types are those whose values are
- logically indivisible; {composite type} {component} composite types are those
- whose values are composed of component values. {aggregate: see also
- composite type}
-
- 2.a Glossary entry: {Class} {closed under derivation} A class is a
- set of types that is closed under derivation, which means that if a
- given type is in the class, then all types derived from that type are
- also in the class. The set of types of a class share common
- properties, such as their primitive operations.
-
- 2.b Glossary entry: {Elementary type} An elementary type does not
- have components.
-
- 2.c Glossary entry: {Composite type} A composite type has
- components.
- 2.d Glossary entry: {Scalar type} A scalar type is either a
- discrete type or a real type.
-
- 2.e Glossary entry: {Access type} An access type has values that
- designate aliased objects. Access types correspond to ``pointer
- types'' or ``reference types'' in some other languages.
-
- 2.f Glossary entry: {Discrete type} A discrete type is either an
- integer type or an enumeration type. Discrete types may be used, for
- example, in case_statements and as array indices.
-
- 2.g Glossary entry: {Real type} A real type has values that are
- approximations of the real numbers. Floating point and fixed point
- types are real types.
-
- 2.h Glossary entry: {Integer type} Integer types comprise the
- signed integer types and the modular types. A signed integer type
- has a base range that includes both positive and negative numbers,
- and has operations that may raise an exception when the result is
- outside the base range. A modular type has a base range whose lower
- bound is zero, and has operations with ``wraparound'' semantics.
- Modular types subsume what are called ``unsigned types'' in some
- other languages.
-
- 2.i Glossary entry: {Enumeration type} An enumeration type is
- defined by an enumeration of its values, which may be named by
- identifiers or character literals.
-
- 2.j Glossary entry: {Character type} A character type is an
- enumeration type whose values include characters.
-
- 2.k Glossary entry: {Record type} A record type is a composite
- type consisting of zero or more named components, possibly of
- different types.
-
- 2.l Glossary entry: {Record extension} A record extension is a
- type that extends another type by adding additional components.
-
- 2.m Glossary entry: {Array type} An array type is a composite type
- whose components are all of the same type. Components are selected
- by indexing.
-
- 2.n Glossary entry: {Task type} A task type is a composite type
- whose values are tasks, which are active entities that may execute
- concurrently with other tasks. The top-level task of a partition is
- called the environment task.
-
- 2.o Glossary entry: {Protected type} A protected type is a
- composite type whose components are protected from concurrent access
- by multiple tasks.
-
- 2.p Glossary entry: {Private type} A private type is a partial
- view of a type whose full view is hidden from its clients.
-
- 2.q Glossary entry: {Private extension} A private extension is
- like a record extension, except that the components of the extension
- part are hidden from its clients.
-
- 3 {scalar type} The elementary types are the scalar types (discrete and
- real) and the access types (whose values provide access to objects or
- subprograms). {discrete type} {enumeration type} Discrete types are either
- integer types or are defined by enumeration of their values (enumeration
- types). {real type} Real types are either floating point types or fixed
- point types.
-
- 4 The composite types are the record types, record extensions, array types,
- task types, and protected types. {private type} {private extension} A
- private type or private extension represents a partial view (see 7.3) of a
- type, providing support for data abstraction. A partial view is a composite
- type.
-
- 4.a To be honest: The set of all record types do not form a class
- (because tagged record types can have private extensions), though the
- set of untagged record types do. In any case, what record types had
- in common in Ada 83 (component selection) is now a property of the
- composite class, since all composite types (other than array types)
- can have discriminants. Similarly, the set of all private types do
- not form a class (because tagged private types can have record
- extensions), though the set of untagged private types do.
- Nevertheless, the set of untagged private types is not particularly
- ``interesting'' -- more interesting is the set of all nonlimited
- types, since that is what a generic formal (nonlimited) private type
- matches.
-
- 5 {discriminant} Certain composite types (and partial views thereof) have
- special components called discriminants whose values affect the presence,
- constraints, or initialization of other components. Discriminants can be
- thought of as parameters of the type.
-
- 6 {subcomponent} The term subcomponent is used in this International
- Standard in place of the term component to indicate either a component, or a
- component of another subcomponent. Where other subcomponents are excluded,
- the term component is used instead. {part (of an object or value)}
- Similarly, a part of an object or value is used to mean the whole object or
- value, or any set of its subcomponents.
-
- 6.a Discussion: The definition of ``part'' here is designed to
- simplify rules elsewhere. By design, the intuitive meaning of
- ``part'' will convey the correct result to the casual reader, while
- this formalistic definition will answer the concern of the
- compiler-writer.
-
- 6.b We use the term ``part'' when talking about the parent part,
- ancestor part, or extension part of a type extension. In contexts
- such as these, the part might represent an empty set of subcomponents
- (e.g. in a null record extension, or a nonnull extension of a null
- record). We also use ``part'' when specifying rules such as those
- that apply to an object with a ``controlled part'' meaning that it
- applies if the object as a whole is controlled, or any subcomponent
- is.
-
- 7 {constraint [partial]} The set of possible values for an object of a
- given type can be subjected to a condition that is called a constraint {null
- constraint} (the case of a null constraint that specifies no restriction is
- also included)[; the rules for which values satisfy a given kind of
- constraint are given in 3.5 for range_constraints, 3.6.1 for index_
- constraints, and 3.7.1 for discriminant_constraints].
-
- 8 {subtype} A subtype of a given type is a combination of the type, a
- constraint on values of the type, and certain attributes specific to the
- subtype. The given type is called the type of the subtype. Similarly, the
- associated constraint is called the constraint of the subtype. The set of
- values of a subtype consists of the values of its type that satisfy its
- constraint. {belong (to a subtype)} Such values belong to the subtype.
-
- 8.a Discussion: We make a strong distinction between a type and
- its subtypes. In particular, a type is not a subtype of itself.
- There is no constraint associated with a type (not even a null one),
- and type-related attributes are distinct from subtype-specific
- attributes.
-
- 8.b Discussion: We no longer use the term "base type." All types
- were "base types" anyway in Ada 83, so the term was redundant, and
- occasionally confusing. In the RM9X we say simply "the type of the
- subtype" instead of "the base type of the subtype."
-
- 8.c Ramification: The value subset for a subtype might be empty,
- and need not be a proper subset.
-
- 8.d To be honest: Any name of a class of types (such as
- ``discrete'' or ``real''), or other category of types (such as
- ``limited'' or ``incomplete'') is also used to qualify its subtypes,
- as well as its objects, values, declarations, and definitions, such
- as an ``integer type declaration'' or an ``integer value.'' In
- addition, if a term such as ``parent subtype'' or ``index subtype''
- is defined, then the corresponding term for the type of the subtype
- is ``parent type'' or ``index type.''
-
- 8.e Discussion: We use these corresponding terms without
- explicitly defining them, when the meaning is obvious.
-
- 9 {constrained} {unconstrained} {constrained (subtype)} {unconstrained
- (subtype)} A subtype is called an unconstrained subtype if its type has
- unknown discriminants, or if its type allows range, index, or discriminant
- constraints, but the subtype does not impose such a constraint; otherwise,
- the subtype is called a constrained subtype (since it has no unconstrained
- characteristics).
-
- 9.a Discussion: In an earlier version of Ada 9X, "constrained"
- meant "has a non-null constraint." However, we changed to this
- definition since we kept having to special case composite
- non-array/non-discriminated types. It also corresponds better to the
- (now obsolescent) attribute 'Constrained.
-
- 9.b For scalar types, ``constrained'' means ``has a non-null
- constraint''. For composite types, in implementation terms,
- ``constrained'' means that the size of all objects of the subtype is
- the same, assuming a typical implementation model.
-
- 9.c Class-wide subtypes are always unconstrained.
-
-
- NOTES
- 10 (2) Any set of types that is closed under derivation (see 3.4) can be
- called a ``class'' of types. However, only certain classes are used in
- the description of the rules of the language -- generally those that
- have their own particular set of primitive operations (see 3.2.3), or
- that correspond to a set of types that are matched by a given kind of
- generic formal type (see 12.5). {language-defined class [partial]} The
- following are examples of ``interesting'' language-defined classes:
- elementary, scalar, discrete, enumeration, character, boolean, integer,
- signed integer, modular, real, floating point, fixed point, ordinary
- fixed point, decimal fixed point, numeric, access, access-to-object,
- access-to-subprogram, composite, array, string, (untagged) record,
- tagged, task, protected, nonlimited. Special syntax is provided to
- define types in each of these classes.
-
- 10.a Discussion: {value} A value is a run-time entity with a given
- type which can be assigned to an object of an appropriate subtype of
- the type. {operation} An operation is a program entity that operates
- on zero or more operands to produce an effect, or yield a result, or
- both.
-
- 10.b Ramification: Note that a type's class depends on the place
- of the reference -- a private type is composite outside and possibly
- elementary inside. It's really the view that is elementary or
- composite. Note that although private types are composite, there are
- some properties that depend on the corresponding full view -- for
- example, parameter passing modes, and the constraint checks that
- apply in various places.
-
- 10.c Not every property of types represents a class. For example,
- the set of all abstract types does not form a class, because this set
- is not closed under derivation.
-
- 10.d The set of limited types forms a class in the sense that it is
- closed under derivation, but the more interesting class, from the
- point of generic formal type matching, is the set of all types,
- limited and nonlimited, since that is what matches a generic formal
- ``limited'' private type. Note also that a limited type can ``become
- nonlimited'' under certain circumstances, which makes ``limited''
- somewhat problematic as a class of types.
-
- 11 These language-defined classes are organized like this:
-
- 12
- all types
- elementary
- scalar
- discrete
- enumeration
- character
- boolean
- other enumeration
- integer
- signed integer
- modular integer
- real
- floating point
- fixed point
- ordinary fixed point
- decimal fixed point
- access
- access-to-object
- access-to-subprogram
- composite
- array
- string
- other array
- untagged record
- tagged
- task
- protected
-
- 13 The classes ``numeric'' and ``nonlimited'' represent other
- classification dimensions and do not fit into the above strictly
- hierarchical picture.
-
-
- Wording Changes From Ada 83
-
- 13.a This clause and its subclauses now precede the clause and
- subclauses on objects and named numbers, to cut down on the number of
- forward references.
-
- 13.b We have dropped the term "base type" in favor of simply "type"
- (all types in Ada 83 were "base types" so it wasn't clear when it was
- appropriate/necessary to say "base type"). Given a subtype S of a
- type T, we call T the "type of the subtype S."
-
-
-
- 3.2.1 Type Declarations
-
- 1 A type_declaration declares a type and its first subtype.
-
-
- Syntax
-
- 2 type_declaration ::= full_type_declaration
- | incomplete_type_declaration
- | private_type_declaration
- | private_extension_declaration
-
- 3 full_type_declaration ::=
- type defining_identifier [known_discriminant_part] is type_definition;
- | task_type_declaration
- | protected_type_declaration
-
- 4 type_definition ::=
- enumeration_type_definition | integer_type_definition
- | real_type_definition | array_type_definition
- | record_type_definition | access_type_definition
- | derived_type_definition
-
-
- Legality Rules
-
- 5 A given type shall not have a subcomponent whose type is the given type
- itself.
-
-
- Static Semantics
-
- 6 {first subtype} The defining_identifier of a type_declaration denotes the
- first subtype of the type. The known_discriminant_part, if any, defines the
- discriminants of the type (see 3.7, ``Discriminants''). The remainder of the
- type_declaration defines the remaining characteristics of (the view of) the
- type.
-
- 7 {named type} A type defined by a type_declaration is a named type; such a
- type has one or more nameable subtypes. {anonymous type} Certain other forms
- of declaration also include type definitions as part of the declaration for
- an object (including a parameter or a discriminant). The type defined by
- such a declaration is anonymous -- it has no nameable subtypes. {italics
- (pseudo-names of anonymous types)} For explanatory purposes, this
- International Standard sometimes refers to an anonymous type by a
- pseudo-name, written in italics, and uses such pseudo-names at places where
- the syntax normally requires an identifier. For a named type whose first
- subtype is T, this International Standard sometimes refers to the type of T
- as simply ``the type T.''
-
- 7.a Ramification: The only user-defined types that can be
- anonymous in the above sense are array, access, task, and protected
- types. An anonymous array, task, or protected type can be defined as
- part of an object_declaration. An anonymous access type can be
- defined as part of a parameter or discriminant specification.
-
- 8 {full type} A named type that is declared by a full_type_declaration, or
- an anonymous type that is defined as part of declaring an object of the type,
- is called a full type. {full type definition} The type_definition, task_
- definition, protected_definition, or access_definition that defines a full
- type is called a full type definition.[Types declared by other forms of type_
- declaration are not separate types; they are partial or incomplete views of
- some full type.]
-
- 8.a To be honest: Class-wide, universal, and root numeric types
- are full types.
-
- 9 {predefined operator [partial]} The definition of a type implicitly
- declares certain predefined operators that operate on the type, according to
- what classes the type belongs, as specified in 4.5, ``Operators and
- Expression Evaluation''.
-
- 9.a Discussion: We no longer talk about the implicit declaration
- of basic operations. These are treated like an if_statement -- they
- don't need to be declared, but are still applicable to only certain
- classes of types.
-
- 10 {predefined type} The predefined types [(for example the types Boolean,
- Wide_Character, Integer, root_integer, and universal_integer)] are the types
- that are defined in [a predefined library package called] Standard[; this
- package also includes the [(implicit)] declarations of their predefined
- operators]. [The package Standard is described in A.1.]
-
- 10.a Ramification: We use the term ``predefined'' to refer to
- entities declared in the visible part of Standard, to implicitly
- declared operators of a type whose semantics are defined by the
- language, to Standard itself, and to the ``predefined environment''.
- We do not use this term to refer to library packages other than
- Standard. For example Text_IO is a language-defined package, not a
- predefined package, and Text_IO.Put_Line is not a predefined
- operation.
-
-
- Dynamic Semantics
-
- 11 {elaboration [full_type_declaration]} The elaboration of a full_type_
- declaration consists of the elaboration of the full type definition.
- {elaboration [full type definition]} Each elaboration of a full type
- definition creates a distinct type and its first subtype.
-
- 11.a Reason: The creation is associated with the type definition,
- rather than the type declaration, because there are types that are
- created by full type definitions that are not immediately contained
- within a type declaration (e.g. an array object declaration, a
- singleton task declaration, etc.).
-
- 11.b Ramification: Any implicit declarations that occur
- immediately following the full type definition are elaborated where
- they (implicitly) occur.
-
-
- Examples
-
- 12 Examples of type definitions:
-
- 13 (White, Red, Yellow, Green, Blue, Brown, Black)
- range 1 .. 72
- array(1 .. 10) of Integer
-
- 14 Examples of type declarations:
-
- 15 type Color is (White, Red, Yellow, Green, Blue, Brown, Black);
- type Column is range 1 .. 72;
- type Table is array(1 .. 10) of Integer;
-
-
- NOTES
- 16 (3) Each of the above examples declares a named type. The identifier
- given denotes the first subtype of the type. Other named subtypes of
- the type can be declared with subtype_declarations (see 3.2.2).
- Although names do not directly denote types, a phrase like ``the type
- Column'' is sometimes used in this International Standard to refer to
- the type of Column, where Column denotes the first subtype of the type.
- For an example of the definition of an anonymous type, see the
- declaration of the array Color_Table in 3.3.1; its type is anonymous --
- it has no nameable subtypes.
- Wording Changes From Ada 83
-
- 16.a The syntactic category full_type_declaration now includes task
- and protected type declarations.
-
- 16.b We have generalized the concept of first-named subtype (now
- called simply ``first subtype'') to cover all kinds of types, for
- uniformity of description elsewhere. RM83 defined first-named
- subtype in Section 13. We define first subtype here, because it is
- now a more fundamental concept. We renamed the term, because in Ada
- 9X some first subtypes have no name.
-
- 16.c We no longer elaborate discriminant_parts, because there is
- nothing to do, and it was complex to say that you only wanted to
- elaborate it once for a private or incomplete type. This is also
- consistent with the fact that subprogram specifications are not
- elaborated (neither in Ada 83 nor in Ada 9X). Note, however, that an
- access_definition appearing in a discriminant_part is elaborated when
- an object with such a discriminant is created.
-
-
-
- 3.2.2 Subtype Declarations
-
- 1 A subtype_declaration declares a subtype of some previously declared
- type, as defined by a subtype_indication.
-
-
- Syntax
-
- 2 subtype_declaration ::=
- subtype defining_identifier is subtype_indication;
-
- 3 subtype_indication ::= subtype_mark [constraint]
-
- 4 subtype_mark ::= subtype_name
-
- 4.a Ramification: Note that name includes attribute_reference;
- thus, S'Base can be used as a subtype_mark.
-
- 4.b Reason: We considered changing subtype_mark to subtype_name.
- However, existing users are used to the word "mark," so we're keeping
- it.
-
- 5 constraint ::= scalar_constraint | composite_constraint
-
- 6 scalar_constraint ::=
- range_constraint | digits_constraint | delta_constraint
-
- 7 composite_constraint ::=
- index_constraint | discriminant_constraint
-
-
- Name Resolution Rules
-
- 8 A subtype_mark shall resolve to denote a subtype. {determines (a type by
- a subtype_mark)} The type determined by a subtype_mark is the type of the
- subtype denoted by the subtype_mark.
-
- 8.a Ramification: Types are never directly named; all subtype_
- marks denote subtypes -- possibly an unconstrained (base) subtype,
- but never the type. When we use the term anonymous type we really
- mean a type with no namable subtypes.
-
-
- Dynamic Semantics
-
- 9 {elaboration [subtype_declaration]} The elaboration of a subtype_
- declaration consists of the elaboration of the subtype_indication.
- {elaboration [subtype_indication]} The elaboration of a subtype_indication
- creates a new subtype. If the subtype_indication does not include a
- constraint, the new subtype has the same (possibly null) constraint as that
- denoted by the subtype_mark. The elaboration of a subtype_indication that
- includes a constraint proceeds as follows:
-
- 10 The constraint is first elaborated.
-
- 11 {Range_Check [partial]} {check, language-defined (Range_Check)} A
- check is then made that the constraint is compatible with the
- subtype denoted by the subtype_mark.
-
- 11.a Ramification: The checks associated with constraint
- compatibility are all Range_Checks. Discriminant_Checks and
- Index_Checks are associated only with checks that a value
- satisfies a constraint.
-
- 12 The condition imposed by a constraint is the condition obtained after
- elaboration of the constraint. {compatibility (constraint with a subtype)
- [distributed]} The rules defining compatibility are given for each form of
- constraint in the appropriate subclause. These rules are such that if a
- constraint is compatible with a subtype, then the condition imposed by the
- constraint cannot contradict any condition already imposed by the subtype on
- its values. {Constraint_Error (raised by failure of run-time check)} The
- exception Constraint_Error is raised if any check of compatibility fails.
-
- 12.a To be honest: The condition imposed by a constraint is named
- after it -- a range_constraint imposes a range constraint, etc.
-
- 12.b Ramification: A range_constraint causes freezing of its type.
- Other constraints do not.
-
-
- NOTES
- 13 (4) A scalar_constraint may be applied to a subtype of an appropriate
- scalar type (see 3.5, 3.5.9, and J.3), even if the subtype is already
- constrained. On the other hand, a composite_constraint may be applied
- to a composite subtype (or an access-to-composite subtype) only if the
- composite subtype is unconstrained (see 3.6.1 and 3.7.1).
-
-
- Examples
-
- 14 Examples of subtype declarations:
-
- 15 subtype Rainbow is Color range Red .. Blue; -- see 3.2.1
- subtype Red_Blue is Rainbow;
- subtype Int is Integer;
- subtype Small_Int is Integer range -10 .. 10;
- subtype Up_To_K is Column range 1 .. K; -- see 3.2.1
- subtype Square is Matrix(1 .. 10, 1 .. 10); -- see 3.6
- subtype Male is Person(Sex => M); -- see 3.10.1
-
-
- Incompatibilities With Ada 83
-
- 15.a {incompatibilities with Ada 83} In Ada 9X, all range_
- constraints cause freezing of their type. Hence, a type-related
- representation item for a scalar type has to precede any range_
- constraints whose type is the scalar type.
-
- Wording Changes From Ada 83
-
- 15.b Subtype_marks allow only subtype names now, since types are
- never directly named. There is no need for RM83-3.3.2(3), which says
- a subtype_mark can denote both the type and the subtype; in Ada 9X,
- you denote an unconstrained (base) subtype if you want, but never the
- type.
-
- 15.c The syntactic category type_mark is now called subtype_mark,
- since it always denotes a subtype.
-
-
-
- 3.2.3 Classification of Operations
-
- Static Semantics
-
- 1 {operates on a type} An operation operates on a type T if it yields a
- value of type T, if it has an operand whose expected type (see 8.6) is T, or
- if it has an access parameter (see 6.1) designating T. {predefined operation
- (of a type)} A predefined operator, or other language-defined operation such
- as assignment or a membership test, that operates on a type, is called a
- predefined operation of the type. {primitive operations (of a type)} The
- primitive operations of a type are the predefined operations of the type,
- plus any user-defined primitive subprograms.
-
- 1.a Glossary entry: {Primitive operations} The primitive
- operations of a type are the operations (such as subprograms)
- declared together with the type declaration. They are inherited by
- other types in the same class of types. For a tagged type, the
- primitive subprograms are dispatching subprograms, providing run-time
- polymorphism. A dispatching subprogram may be called with statically
- tagged operands, in which case the subprogram body invoked is
- determined at compile time. Alternatively, a dispatching subprogram
- may be called using a dispatching call, in which case the subprogram
- body invoked is determined at run time.
-
- 1.b To be honest: Protected subprograms are not considered to be
- ``primitive subprograms,'' even though they are subprograms, and they
- are inherited by derived types.
-
- 1.c Discussion: We use the term ``primitive subprogram'' in most
- of the rest of the manual. The term ``primitive operation'' is used
- mostly in conceptual discussions.
-
- 2 {primitive subprograms (of a type)} The primitive subprograms of a
- specific type are defined as follows:
-
- 3 The predefined operators of the type (see 4.5);
-
- 4 For a derived type, the inherited (see 3.4) user-defined
- subprograms;
-
- 5 For an enumeration type, the enumeration literals (which are
- considered parameterless functions -- see 3.5.1);
-
- 6 For a specific type declared immediately within a package_
- specification, any subprograms (in addition to the enumeration
- literals) that are explicitly declared immediately within the
- same package_specification and that operate on the type;
-
- 7 {override (a primitive subprogram)} Any subprograms not covered
- above [that are explicitly declared immediately within the same
- declarative region as the type] and that override (see 8.3) other
- implicitly declared primitive subprograms of the type.
- {94-4450.a} {94-4451.a} {94-4453.a}
-
- 7.a Discussion: In Ada 83, only subprograms declared in the
- visible part were ``primitive'' (i.e. derivable). In Ada 9X, mostly
- because of child library units, we include all operations declared in
- the private part as well, and all operations that override implicit
- declarations.
-
- 7.b Ramification: It is possible for a subprogram to be primitive
- for more than one type, though it is illegal for a subprogram to be
- primitive for more than one tagged type. See 3.9.
-
- 7.c Discussion: The order of the implicit declarations when there
- are both predefined operators and inherited subprograms is described
- in 3.4, ``Derived Types and Classes''.
-
- 8 {primitive operator (of a type)} A primitive subprogram whose designator
- is an operator_symbol is called a primitive operator.
-
-
- Incompatibilities With Ada 83
-
- 8.a {incompatibilities with Ada 83} The attribute S'Base is no
- longer defined for non-scalar subtypes. Since this was only
- permitted as the prefix of another attribute, and there are no
- interesting non-scalar attributes defined for an unconstrained
- composite or access subtype, this should not affect any existing
- programs.
-
- Extensions to Ada 83
-
- 8.b {extensions to Ada 83} The primitive subprograms (derivable
- subprograms) include subprograms declared in the private part of a
- package specification as well, and those that override implicitly
- declared subprograms, even if declared in a body.
-
- Wording Changes From Ada 83
-
- 8.c We have dropped the confusing term operation of a type in favor
- of the more useful primitive operation of a type and the phrase
- operates on a type.
-
- 8.d The description of S'Base has been moved to 3.5, ``Scalar
- Types'' because it is now defined only for scalar types.
-
-
-
- 3.3 Objects and Named Numbers
-
- 1 [Objects are created at run time and contain a value of a given type.
- {creation (of an object)} An object can be created and initialized as part of
- elaborating a declaration, evaluating an allocator, aggregate, or function_
- call, or passing a parameter by copy. Prior to reclaiming the storage for an
- object, it is finalized if necessary (see 7.6.1).]
-
-
- Static Semantics
-
- 2 {object} All of the following are objects:
-
- 2.a Glossary entry: {Object} An object is either a constant or a
- variable. An object contains a value. An object is created by an
- object_declaration or by an allocator. A formal parameter is (a view
- of) an object. A subcomponent of an object is an object.
-
- 3 the entity declared by an object_declaration;
-
- 4 a formal parameter of a subprogram, entry, or generic subprogram;
-
- 5 a generic formal object;
-
- 6 a loop parameter;
-
- 7 a choice parameter of an exception_handler;
-
- 8 an entry index of an entry_body;
-
- 9 the result of dereferencing an access-to-object value (see 4.1);
-
- 10 the result of evaluating a function_call (or the equivalent
- operator invocation -- see 6.6);
-
- 11 the result of evaluating an aggregate;
-
- 12 a component, slice, or view conversion of another object.
-
- 13 {constant} {variable} {constant object} {variable object} {constant
- view} {variable view} An object is either a constant object or a variable
- object. The value of a constant object cannot be changed between its
- initialization and its finalization, whereas the value of a variable object
- can be changed. Similarly, a view of an object is either a constant or a
- variable. All views of a constant object are constant. A constant view of a
- variable object cannot be used to modify the value of the variable. The
- terms constant and variable by themselves refer to constant and variable
- views of objects.
-
- 14 {read (the value of an object)} The value of an object is read when the
- value of any part of the object is evaluated, or when the value of an
- enclosing object is evaluated. {update (the value of an object)} The value
- of a variable is updated when an assignment is performed to any part of the
- variable, or when an assignment is performed to an enclosing object.
-
- 14.a Ramification: Reading and updating are intended to include
- read/write references of any kind, even if they are not associated
- with the evaluation of a particular construct. Consider, for
- example, the expression ``X.all(F)'', where X is an access-to-array
- object, and F is a function. The implementation is allowed to first
- evaluate ``X.all'' and then F. Finally, a read is performed to get
- the value of the F'th component of the array. Note that the array is
- not necessarily read as part of the evaluation of ``X.all''. This is
- important, because if F were to free X using Unchecked_Deallocation,
- we want the execution of the final read to be erroneous.
-
- 15 Whether a view of an object is constant or variable is determined by the
- definition of the view. The following (and no others) represent constants:
-
- 16 an object declared by an object_declaration with the reserved
- word constant;
-
- 17 a formal parameter or generic formal object of mode in;
-
- 18 a discriminant;
-
- 19 a loop parameter, choice parameter, or entry index;
-
- 20 the dereference of an access-to-constant value;
-
- 21 the result of evaluating a function_call or an aggregate;
-
- 22 a selected_component, indexed_component, slice, or view
- conversion of a constant.
-
- 22.a To be honest: A noninvertible view conversion to a general
- access type is also defined to be a constant -- see 4.6.
-
- 23 {nominal subtype} At the place where a view of an object is defined, a
- nominal subtype is associated with the view. {actual subtype} {subtype (of
- an object): see actual subtype of an object} The object's actual subtype
- (that is, its subtype) can be more restrictive than the nominal subtype of
- the view; it always is if the nominal subtype is an indefinite subtype.
- {indefinite subtype} {definite subtype} A subtype is an indefinite subtype if
- it is an unconstrained array subtype, or if it has unknown discriminants or
- unconstrained discriminants without defaults (see 3.7); otherwise the subtype
- is a definite subtype [(all elementary subtypes are definite subtypes)].[A
- class-wide subtype is defined to have unknown discriminants, and is therefore
- an indefinite subtype. An indefinite subtype does not by itself provide
- enough information to create an object; an additional constraint or explicit
- initialization expression is necessary (see 3.3.1). A component cannot have
- an indefinite nominal subtype. {94-4799.a}]
-
- 24 {named number} A named number provides a name for a numeric value known
- at compile time. It is declared by a number_declaration.
-
-
- NOTES
- 25 (5) A constant cannot be the target of an assignment operation, nor be
- passed as an in out or out parameter, between its initialization and
- finalization, if any.
-
- 26 (6) The nominal and actual subtypes of an elementary object are always
- the same. For a discriminated or array object, if the nominal subtype
- is constrained then so is the actual subtype.
-
-
- Extensions to Ada 83
-
- 26.a {extensions to Ada 83} There are additional kinds of objects
- (choice parameters and entry indices of entry bodies).
-
- 26.b The result of a function and of evaluating an aggregate are
- considered (constant) objects. This is necessary to explain the
- action of finalization on such things. Because a function_call is
- also syntactically a name (see 4.1), the result of a function_call
- can be renamed, thereby allowing repeated use of the result without
- calling the function again.
-
- Wording Changes From Ada 83
-
- 26.c This clause and its subclauses now follow the clause and
- subclauses on types and subtypes, to cut down on the number of
- forward references.
-
- 26.d The term nominal subtype is new. It is used to distinguish
- what is known at compile time about an object's constraint, versus
- what its "true" run-time constraint is.
-
- 26.e The terms definite and indefinite (which apply to subtypes)
- are new. They are used to aid in the description of generic formal
- type matching, and to specify when an explicit initial value is
- required in an object_declaration.
-
- 26.f We have moved the syntax for object_declaration and number_
- declaration down into their respective subclauses, to keep the syntax
- close to the description of the associated semantics.
-
- 26.g We talk about variables and constants here, since the
- discussion is not specific to object_declarations, and it seems
- better to have the list of the kinds of constants juxtaposed with the
- kinds of objects.
-
- 26.h We no longer talk about indirect updating due to parameter
- passing. Parameter passing is handled in 6.2 and 6.4.1 in a way that
- there is no need to mention it here in the definition of read and
- update. Reading and updating now includes the case of evaluating or
- assigning to an enclosing object.
- 3.3.1 Object Declarations
-
- 1 {stand-alone object} {explicit initial value} {initialization expression}
- An object_declaration declares a stand-alone object with a given nominal
- subtype and, optionally, an explicit initial value given by an initialization
- expression. {anonymous array type} {anonymous task type} {anonymous
- protected type} For an array, task, or protected object, the object_
- declaration may include the definition of the (anonymous) type of the object.
-
-
- Syntax
-
- 2 object_declaration ::=
- defining_identifier_list : [aliased] [constant] subtype_indication [:= \
- expression];
- | defining_identifier_list : [aliased] [constant] array_type_definition [\
- := expression];
- | single_task_declaration
- | single_protected_declaration
-
- 3 defining_identifier_list ::=
- defining_identifier {, defining_identifier}
-
-
- Name Resolution Rules
-
- 4 {expected type [object_declaration initialization expression]} For an
- object_declaration with an expression following the compound delimiter :=,
- the type expected for the expression is that of the object. {initialization
- expression} This expression is called the initialization expression.
- {constructor: see initialization expression}
-
-
- Legality Rules
-
- 5 An object_declaration without the reserved word constant declares a
- variable object. If it has a subtype_indication or an array_type_definition
- that defines an indefinite subtype, then there shall be an initialization
- expression. An initialization expression shall not be given if the object is
- of a limited type.
-
-
- Static Semantics
-
- 6 An object_declaration with the reserved word constant declares a constant
- object. {full constant declaration} If it has an initialization expression,
- then it is called a full constant declaration. {deferred constant
- declaration} Otherwise it is called a deferred constant declaration. The
- rules for deferred constant declarations are given in clause 7.4. The rules
- for full constant declarations are given in this subclause.
-
- 7 Any declaration that includes a defining_identifier_list with more than
- one defining_identifier is equivalent to a series of declarations each
- containing one defining_identifier from the list, with the rest of the text
- of the declaration copied for each declaration in the series, in the same
- order as the list. The remainder of this International Standard relies on
- this equivalence; explanations are given for declarations with a single
- defining_identifier.
-
- 8 {nominal subtype} The subtype_indication or full type definition of an
- object_declaration defines the nominal subtype of the object. The object_
- declaration declares an object of the type of the nominal subtype.
-
- 8.a Discussion: The phrase ``full type definition'' here includes
- the case of an anonymous array, task, or protected type.
-
-
- Dynamic Semantics
-
- 9 {constraint (of an object)} If a composite object declared by an object_
- declaration has an unconstrained nominal subtype, then if this subtype is
- indefinite or the object is constant or aliased (see 3.10) the actual subtype
- of this object is constrained. The constraint is determined by the bounds or
- discriminants (if any) of its initial value; {constrained by its initial
- value} the object is said to be constrained by its initial value. {actual
- subtype (of an object)} {subtype (of an object): see actual subtype of an
- object} [In the case of an aliased object, this initial value may be either
- explicit or implicit; in the other cases, an explicit initial value is
- required.] {94-4858.a} When not constrained by its initial value, the actual
- and nominal subtypes of the object are the same. {constrained (object)}
- {unconstrained (object)} If its actual subtype is constrained, the object is
- called a constrained object.
-
- 10 {implicit initial values (for a subtype)} For an object_declaration
- without an initialization expression, any initial values for the object or
- its subcomponents are determined by the implicit initial values defined for
- its nominal subtype, as follows:
-
- 11 The implicit initial value for an access subtype is the null
- value of the access type.
-
- 12 The implicit initial (and only) value for each discriminant of a
- constrained discriminated subtype is defined by the subtype.
-
- 13 For a (definite) composite subtype, the implicit initial value of
- each component with a default_expression is obtained by
- evaluation of this expression and conversion to the component's
- nominal subtype (which might raise Constraint_Error -- see 4.6,
- ``Type Conversions''), unless the component is a discriminant of
- a constrained subtype (the previous case), or is in an excluded
- variant (see 3.8.1). {implicit subtype conversion [component
- defaults]} For each component that does not have a default_
- expression, any implicit initial values are those determined by
- the component's nominal subtype.
-
- 14 For a protected or task subtype, there is an implicit component
- (an entry queue) corresponding to each entry, with its implicit
- initial value being an empty queue.
-
- 14.a Implementation Note: The implementation may add implicit
- components for its own use, which might have implicit initial
- values. For a task subtype, such components might represent the
- state of the associated thread of control. For a type with
- dynamic-sized components, such implicit components might be used
- to hold the offset to some explicit component.
-
- 15 {elaboration [object_declaration]} The elaboration of an object_
- declaration proceeds in the following sequence of steps:
-
- 16 The subtype_indication, array_type_definition, single_task_
- declaration, or single_protected_declaration is first elaborated.
- This creates the nominal subtype (and the anonymous type in the
- latter three cases).
-
- 17 If the object_declaration includes an initialization expression,
- the (explicit) initial value is obtained by evaluating the
- expression and converting it to the nominal subtype (which might
- raise Constraint_Error -- see 4.6). {implicit subtype conversion
- [initialization expression]}
-
- 18 The object is created, and, if there is not an initialization
- expression, any per-object expressions (see 3.8) are evaluated
- and any implicit initial values for the object or for its
- subcomponents are obtained as determined by the nominal subtype.
-
- 18.a Discussion: For a per-object constraint that contains some
- per-object expressions and some non-per-object expressions, the
- values used for the constraint consist of the values of the
- non-per-object expressions evaluated at the point of the type_
- declaration, and the values of the per-object expressions
- evaluated at the point of the creation of the object.
-
- 18.b The elaboration of per-object constraints was presumably
- performed as part of the dependent compatibility check in Ada
- 83. If the object is of a limited type with an access
- discriminant, the access_definition is elaborated at this time
- (see 3.7).
-
- 18.c Reason: The reason we say that evaluating an explicit
- initialization expression happens before creating the object is
- that in some cases it is impossible to know the size of the
- object being created until its initial value is known, as in
- ``X: String := Func_Call(...);''. The implementation can create
- the object early in the common case where the size can be known
- early, since this optimization is semantically neutral.
-
- 19 {initialization (of an object)} {assignment operation (during
- elaboration of an object_declaration)} Any initial values
- (whether explicit or implicit) are assigned to the object or to
- the corresponding subcomponents. As described in 5.2 and 7.6,
- Initialize and Adjust procedures can be called. {constructor:
- see initialization}
-
- 19.a Ramification: Since the initial values have already been
- converted to the appropriate nominal subtype, the only
- Constraint_Errors that might occur as part of these assignments
- are for values outside their base range that are used to
- initialize unconstrained numeric subcomponents. See 3.5.
-
- 20 For the third step above, the object creation and any elaborations and
- evaluations are performed in an arbitrary order, except that if the default_
- expression for a discriminant is evaluated to obtain its initial value, then
- this evaluation is performed before that of the default_expression for any
- component that depends on the discriminant, and also before that of any
- default_expression that includes the name of the discriminant. The
- evaluations of the third step and the assignments of the fourth step are
- performed in an arbitrary order, except that each evaluation is performed
- before the resulting value is assigned.
-
- 20.a Reason: For example:
-
- 20.b type R(D : Integer := F) is
- record
- S : String(1..D) := (others => G);
- end record;
-
- 20.c X : R;
-
- 20.d For the elaboration of the declaration of X, it is important
- that F be evaluated before the aggregate.
-
- 21 [There is no implicit initial value defined for a scalar subtype.]
- {uninitialized variables [partial]} In the absence of an explicit
- initialization, a newly created scalar object might have a value that does
- not belong to its subtype (see 13.9.1 and H.1).
-
- 21.a To be honest: It could even be represented by a bit pattern
- that doesn't actually represent any value of the type at all, such as
- an invalid internal code for an enumeration type, or a NaN for a
- floating point type. It is a generally a bounded error to reference
- scalar objects with such ``invalid representations'', as explained in
- 13.9.1, ``Data Validity''.
- 21.b Ramification: There is no requirement that two objects of the
- same scalar subtype have the same implicit initial ``value'' (or
- representation). It might even be the case that two elaborations of
- the same object_declaration produce two different initial values.
- However, any particular uninitialized object is default-initialized
- to a single value (or invalid representation). Thus, multiple reads
- of such an uninitialized object will produce the same value each time
- (if the implementation chooses not to detect the error).
-
-
- NOTES
- 22 (7) Implicit initial values are not defined for an indefinite subtype,
- because if an object's nominal subtype is indefinite, an explicit
- initial value is required. {94-4799.a}
-
- 23 (8) {stand-alone constant} {stand-alone variable} As indicated above, a
- stand-alone object is an object declared by an object_declaration.
- Similar definitions apply to ``stand-alone constant'' and ``stand-alone
- variable.'' A subcomponent of an object is not a stand-alone object,
- nor is an object that is created by an allocator. An object declared by
- a loop_parameter_specification, parameter_specification, entry_index_
- specification, choice_parameter_specification, or a formal_object_
- declaration is not called a stand-alone object.
-
- 24 (9) The type of a stand-alone object cannot be abstract (see 3.9.3).
-
-
- Examples
-
- 25 Example of a multiple object declaration:
-
- 26 -- the multiple object declaration
-
- 27 John, Paul : Person_Name := new Person(Sex => M); -- see 3.10.1
-
- 28 -- is equivalent to the two single object declarations in the order given
-
- 29 John : Person_Name := new Person(Sex => M);
- Paul : Person_Name := new Person(Sex => M);
-
- 30 Examples of variable declarations:
-
- 31 Count, Sum : Integer;
- Size : Integer range 0 .. 10_000 := 0;
- Sorted : Boolean := False;
- Color_Table : array(1 .. Max) of Color;
- Option : Bit_Vector(1 .. 10) := (others => True);
- Hello : constant String := "Hi, world.";
-
- 32 Examples of constant declarations:
-
- 33 Limit : constant Integer := 10_000;
- Low_Limit : constant Integer := Limit/10;
- Tolerance : constant Real := Dispersion(1.15);
-
-
- Extensions to Ada 83
-
- 33.a {extensions to Ada 83} The syntax rule for object_declaration
- is modified to allow the aliased reserved word.
-
- 33.b A variable declared by an object_declaration can be
- constrained by its initial value; that is, a variable of a nominally
- unconstrained array subtype, or discriminated type without defaults,
- can be declared so long as it has an explicit initial value. In Ada
- 83, this was permitted for constants, and for variables created by
- allocators, but not for variables declared by object_declarations.
- This is particularly important for tagged class-wide types, since
- there is no way to constrain them explicitly, and so an initial value
- is the only way to provide a constraint. It is also important for
- generic formal private types with unknown discriminants.
-
- 33.c We now allow an unconstrained_array_definition in an object_
- declaration. This allows an object of an anonymous array type to
- have its bounds determined by its initial value. This is for
- uniformity: If one can write ``X: constant array(Integer range 1..10)
- of Integer := ...;'' then it makes sense to also allow ``X: constant
- array(Integer range <>) of Integer := ...;''. (Note that if
- anonymous array types are ever sensible, a common situation is for a
- table implemented as an array. Tables are often constant, and for
- constants, there's usually no point in forcing the user to count the
- number of elements in the value.)
-
- Wording Changes From Ada 83
-
- 33.d We have moved the syntax for object_declarations into this
- subclause.
-
- 33.e Deferred constants no longer have a separate syntax rule, but
- rather are incorporated in object_declaration as constants declared
- without an initialization expression.
-
-
-
- 3.3.2 Number Declarations
-
- 1 A number_declaration declares a named number.
-
- 1.a Discussion: {static} If a value or other property of a
- construct is required to be static that means it is required to be
- determined prior to execution. A static expression is an expression
- whose value is computed at compile time and is usable in contexts
- where the actual value might affect the legality of the construct.
- This is fully defined in clause 4.9.
-
-
- Syntax
-
- 2 number_declaration ::=
- defining_identifier_list : constant := static_expression;
-
-
- Name Resolution Rules
-
- 3 {expected type [number_declaration expression]} The static_expression
- given for a number_declaration is expected to be of any numeric type.
-
-
- Legality Rules
-
- 4 The static_expression given for a number declaration shall be a static
- expression, as defined by clause 4.9.
-
-
- Static Semantics
-
- 5 The named number denotes a value of type universal_integer if the type of
- the static_expression is an integer type. The named number denotes a value
- of type universal_real if the type of the static_expression is a real type.
-
- 6 The value denoted by the named number is the value of the
- static_expression, converted to the corresponding universal type. {implicit
- subtype conversion [named number value]}
-
-
- Dynamic Semantics
-
- 7 {elaboration [number_declaration]} The elaboration of a number_
- declaration has no effect.
-
- 7.a Proof: Since the static_expression was evaluated at compile
- time.
-
-
- Examples
-
- 8 Examples of number declarations:
-
- 9 Two_Pi : constant := 2.0*Ada.Numerics.Pi; -- a real number (see A.\
- 5)
-
- 10 Max : constant := 500; -- an integer number
- Max_Line_Size : constant := Max/6 -- the integer 83
- Power_16 : constant := 2**16; -- the integer 65_536
- One, Un, Eins : constant := 1; -- three different names\
- for 1
-
-
- Extensions to Ada 83
-
- 10.a {extensions to Ada 83} We now allow a static expression of any
- numeric type to initialize a named number. For integer types, it was
- possible in Ada 83 to use 'Pos to define a named number, but there
- was no way to use a static expression of some non-universal real type
- to define a named number. This change is upward compatible because
- of the preference rule for the operators of the root numeric types.
-
- Wording Changes From Ada 83
-
- 10.b We have moved the syntax rule into this subclause.
-
- 10.c AI-00263 describes the elaboration of a number declaration in
- words similar to that of an object_declaration. However, since there
- is no expression to be evaluated and no object to be created, it
- seems simpler to say that the elaboration has no effect.
-
-
-
- 3.4 Derived Types and Classes
-
- 1 {derived type} A derived_type_definition defines a new type (and its
- first subtype) whose characteristics are derived from those of a parent type.
-
- 1.a Glossary entry: {Derived type} A derived type is a type
- defined in terms of another type, which is the parent type of the
- derived type. Each class containing the parent type also contains
- the derived type. The derived type inherits properties such as
- components and primitive operations from the parent. A type together
- with the types derived from it (directly or indirectly) form a
- derivation class.
-
- {inheritance: see derived types and classes}
-
-
- Syntax
-
- 2 derived_type_definition ::= [abstract] new parent_subtype_indication [recor\
- d_extension_part]
-
-
- Legality Rules
- 3 {parent subtype} {parent type} The parent_subtype_indication defines the
- parent subtype; its type is the parent type.
-
- 4 A type shall be completely defined (see 3.11.1) prior to being specified
- as the parent type in a derived_type_definition -- [the full_type_
- declarations for the parent type and any of its subcomponents have to precede
- the derived_type_definition.]
-
- 4.a Discussion: This restriction does not apply to the ancestor
- type of a private extension -- see 7.3; such a type need not be
- completely defined prior to the private_extension_declaration.
- However, the restriction does apply to record extensions, so the
- ancestor type will have to be completely defined prior to the full_
- type_declaration corresponding to the private_extension_declaration.
-
- 4.b Reason: We originally hoped we could relax this restriction.
- However, we found it too complex to specify the rules for a type
- derived from an incompletely defined limited type that subsequently
- became nonlimited.
-
- 5 {record extension} If there is a record_extension_part, the derived type
- is called a record extension of the parent type. A record_extension_part
- shall be provided if and only if the parent type is a tagged type.
-
- 5.a Implementation Note: We allow a record extension to inherit
- discriminants; a previous version of Ada 9X did not. If the parent
- subtype is unconstrained, it can be implemented as though its
- discriminants were repeated in a new known_discriminant_part and then
- used to constrain the old ones one-for-one. However, in an extension
- aggregate, the discriminants in this case do not appear in the
- component association list.
-
- 5.b Ramification: This rule needs to be rechecked in the visible
- part of an instance of a generic unit.
-
-
- Static Semantics
-
- 6 {constrained (subtype)} {unconstrained (subtype)} The first subtype of
- the derived type is unconstrained if a known_discriminant_part is provided in
- the declaration of the derived type, or if the parent subtype is
- unconstrained. {corresponding constraint} Otherwise, the constraint of the
- first subtype corresponds to that of the parent subtype in the following
- sense: it is the same as that of the parent subtype except that for a range
- constraint (implicit or explicit), the value of each bound of its range is
- replaced by the corresponding value of the derived type.
-
- 6.a Discussion: A digits_constraint in a subtype_indication for a
- decimal fixed point subtype always imposes a range constraint,
- implicitly if there is no explicit one given. See 3.5.9, ``Fixed
- Point Types''.
-
- 7 The characteristics of the derived type are defined as follows:
-
- 8 Each class of types that includes the parent type also includes
- the derived type.
-
- 8.a Discussion: This is inherent in our notion of a ``class'' of
- types. It is not mentioned in the initial definition of
- ``class'' since at that point type derivation has not been
- defined. In any case, this rule ensures that every class of
- types is closed under derivation.
-
- 9 If the parent type is an elementary type or an array type, then
- the set of possible values of the derived type is a copy of the
- set of possible values of the parent type. For a scalar type,
- the base range of the derived type is the same as that of the
- parent type.
-
- 9.a Discussion: The base range of a type defined by an integer_
- type_definition or a real_type_definition is determined by the
- _definition, and is not necessarily the same as that of the
- corresponding root numeric type from which the newly defined
- type is implicitly derived. Treating numerics types as
- implicitly derived from one of the two root numeric types is
- simply to link them into a type hierarchy; such an implicit
- derivation does not follow all the rules given here for an
- explicit derived_type_definition.
-
- 10 If the parent type is a composite type other than an array type,
- then the components, protected subprograms, and entries that are
- declared for the derived type are as follows:
-
- 11 The discriminants specified by a new known_discriminant_
- part, if there is one; otherwise, each discriminant of the
- parent type (implicitly declared in the same order with
- the same specifications) -- {inherited discriminant}
- {inherited component} in the latter case, the dis-
- criminants are said to be inherited, or if unknown in the
- parent, are also unknown in the derived type;
-
- 12 Each nondiscriminant component, entry, and protected
- subprogram of the parent type, implicitly declared in the
- same order with the same declarations; {inherited
- component} {inherited protected subprogram} {inherited
- entry} these components, entries, and protected sub-
- programs are said to be inherited;
-
- 12.a Ramification: The profiles of entries and protected subprograms
- do not change upon type derivation, although the type of the
- ``implicit'' parameter identified by the prefix of the name in a
- call does.
-
- 12.b To be honest: Any name in the parent type_declaration that
- denotes the current instance of the type is replaced with a name
- denoting the current instance of the derived type, converted to
- the parent type. {94-4535.d} {94-4537.b}
-
- 13 Each component declared in a record_extension_part, if
- any.
-
- 14 Declarations of components, protected subprograms, and
- entries, whether implicit or explicit, occur immediately within
- the declarative region of the type, in the order indicated above,
- following the parent subtype_indication.
-
- 14.a Discussion: The order of declarations within the region
- matters for record_aggregates and extension_aggregates.
-
- 14.b Ramification: In most cases, these things are implicitly
- declared immediately following the parent subtype_indication.
- However, 7.3.1, ``Private Operations'' defines some cases in
- which they are implicitly declared later, and some cases in
- which the are not declared at all.
-
- 14.c Discussion: The place of the implicit declarations of
- inherited components matters for visibility -- they are not
- visible in the known_discriminant_part nor in the parent
- subtype_indication, but are usually visible within the record_
- extension_part, if any (although there are restrictions on their
- use). Note that a discriminant specified in a new known_
- discriminant_part is not considered ``inherited'' even if it has
- the same name and subtype as a discriminant of the parent type.
-
- 15 The derived type is limited if and only if the parent type is
- limited.
-
- 15.a To be honest: The derived type can become nonlimited if the
- derivation takes place in the visible part of a child package,
- and the parent type is nonlimited as viewed from the private
- part of the child package -- see 7.5.
-
- 16 [For each predefined operator of the parent type, there is a
- corresponding predefined operator of the derived type.]
-
- 16.a Proof: This is a ramification of the fact that each class that
- includes the parent type also includes the derived type, and the
- fact that the set of predefined operators that is defined for a
- type, as described in 4.5, is determined by the classes to which
- it belongs.
-
- 16.b Reason: Predefined operators are handled separately because
- they follow a slightly different rule than user-defined
- primitive subprograms. In particular the systematic replacement
- described below does not apply fully to the relational operators
- for Boolean and the exponentiation operator for Integer. The
- relational operators for a type derived from Boolean still
- return Standard.Boolean. The exponentiation operator for a type
- derived from Integer still expects Standard.Integer for the
- right operand. In addition, predefined operators "reemerge"
- when a type is the actual type corresponding to a generic formal
- type, so they need to be well defined even if hidden by
- user-defined primitive subprograms.
-
- 17 {inherited subprogram} For each user-defined primitive subprogram
- (other than a user-defined equality operator -- see below) of the
- parent type that already exists at the place of the derived_type_
- definition, there exists a corresponding inherited primitive
- subprogram of the derived type with the same defining name.
- {equality operator (special inheritance rule for tagged types)}
- Primitive user-defined equality operators of the parent type are
- also inherited by the derived type, except when the derived type
- is a nonlimited record extension, and the inherited operator
- would have a profile that is type conformant with the profile of
- the corresponding predefined equality operator; in this case, the
- user-defined equality operator is not inherited, but is rather
- incorporated into the implementation of the predefined equality
- operator of the record extension (see 4.5.2). {type conformance
- [partial]}
-
- 17.a Ramification: We say ``...already exists...'' rather
- than ``is visible'' or ``has been declared'' because there are
- certain operations that are declared later, but still exist at
- the place of the derived_type_definition, and there are
- operations that are never declared, but still exist. These
- cases are explained in 7.3.1.
-
- 17.b Note that nonprivate extensions can appear only after the
- last primitive subprogram of the parent -- the freezing rules
- ensure this.
-
- 17.c Reason: A special case is made for the equality
- operators on nonlimited record extensions because their
- predefined equality operators are already defined in terms of
- the primitive equality operator of their parent type (and of the
- tagged components of the extension part). Inheriting the
- parent's equality operator as is would be undesirable, because
- it would ignore any components of the extension part. On the
- other hand, if the parent type is limited, then any user-defined
- equality operator is inherited as is, since there is no
- predefined equality operator to take its place.
-
- 17.d Ramification: Because user-defined equality operators
- are not inherited by record extensions, the formal parameter
- names of = and /= revert to Left and Right, even if different
- formal parameter names were used in the user-defined equality
- operators of the parent type.
-
- 18 The profile of an inherited subprogram (including an
- inherited enumeration literal) is obtained from the profile of
- the corresponding (user-defined) primitive subprogram of the
- parent type, after systematic replacement of each subtype of its
- profile (see 6.1) that is of the parent type with a corresponding
- subtype of the derived type. {corresponding subtype} For a given
- subtype of the parent type, the corresponding subtype of the
- derived type is defined as follows:
-
- 19 If the declaration of the derived type has neither a
- known_discriminant_part nor a record_extension_part, then
- the corresponding subtype has a constraint that
- corresponds (as defined above for the first subtype of the
- derived type) to that of the given subtype.
-
- 20 If the derived type is a record extension, then the
- corresponding subtype is the first subtype of the derived
- type.
-
- 21 If the derived type has a new known_discriminant_part but
- is not a record extension, then the corresponding subtype
- is constrained to those values that when converted to the
- parent type belong to the given subtype (see 4.6).
- {implicit subtype conversion [derived type discriminants]}
-
- 21.a Reason: An inherited subprogram of an untagged type has an
- Intrinsic calling convention, which precludes the use of the
- Access attribute. We preclude 'Access because correctly
- performing all required constraint checks on an indirect call to
- such an inherited subprogram was felt to impose an undesirable
- implementation burden.
-
- 22 The same formal parameters have default_expressions in the
- profile of the inherited subprogram. [Any type mismatch due to
- the systematic replacement of the parent type by the derived type
- is handled as part of the normal type conversion associated with
- parameter passing -- see 6.4.1.]
-
- 22.a Reason: We don't introduce the type conversion
- explicitly here since conversions to record extensions or on
- access parameters are not generally legal. Furthermore, any
- type conversion would just be "undone" since the parent's
- subprogram is ultimately being called anyway.
-
- 23 If a primitive subprogram of the parent type is visible at the place of
- the derived_type_definition, then the corresponding inherited subprogram is
- implicitly declared immediately after the derived_type_definition. Other-
- wise, the inherited subprogram is implicitly declared later or not at all, as
- explained in 7.3.1.
-
- 24 {derived type [partial]} A derived type can also be defined by a
- private_extension_declaration (see 7.3) or a formal_derived_type_definition
- (see 12.5.1). Such a derived type is a partial view of the corresponding
- full or actual type.
-
- 25 All numeric types are derived types, in that they are implicitly derived
- from a corresponding root numeric type (see 3.5.4 and 3.5.6).
-
-
- Dynamic Semantics
-
- 26 {elaboration [derived_type_definition]} The elaboration of a derived_
- type_definition creates the derived type and its first subtype, and consists
- of the elaboration of the subtype_indication and the record_extension_part,
- if any. If the subtype_indication depends on a discriminant, then only those
- expressions that do not depend on a discriminant are evaluated. {94-4535.c}
-
- 27 {execution [call on an inherited subprogram]} For the execution of a
- call on an inherited subprogram, a call on the corresponding primitive
- subprogram of the parent type is performed; the normal conversion of each
- actual parameter to the subtype of the corresponding formal parameter (see
- 6.4.1) performs any necessary type conversion as well. If the result type of
- the inherited subprogram is the derived type, the result of calling the
- parent's subprogram is converted to the derived type. {implicit subtype
- conversion [result of inherited function]}
-
- 27.a Discussion: If an inherited function returns the derived
- type, and the type is a record extension, then the inherited function
- is abstract, and (unless overridden) cannot be called except via a
- dispatching call. See 3.9.3.
-
-
- NOTES
- 28 (10) {closed under derivation} Classes are closed under derivation --
- any class that contains a type also contains its derivatives.
- Operations available for a given class of types are available for the
- derived types in that class.
-
- 29 (11) Evaluating an inherited enumeration literal is equivalent to
- evaluating the corresponding enumeration literal of the parent type, and
- then converting the result to the derived type. This follows from their
- equivalence to parameterless functions. {implicit subtype conversion
- [inherited enumeration literal]}
-
- 30 (12) A generic subprogram is not a subprogram, and hence cannot be a
- primitive subprogram and cannot be inherited by a derived type. On the
- other hand, an instance of a generic subprogram can be a primitive
- subprogram, and hence can be inherited.
-
- 31 (13) If the parent type is an access type, then the parent and the
- derived type share the same storage pool; there is a null access value
- for the derived type and it is the implicit initial value for the type.
- See 3.10.
-
- 32 (14) If the parent type is a boolean type, the predefined relational
- operators of the derived type deliver a result of the predefined type
- Boolean (see 4.5.2). If the parent type is an integer type, the right
- operand of the predefined exponentiation operator is of the predefined
- type Integer (see 4.5.6).
-
- 33 (15) Any discriminants of the parent type are either all inherited, or
- completely replaced with a new set of discriminants.
-
- 34 (16) For an inherited subprogram, the subtype of a formal parameter of
- the derived type need not have any value in common with the first
- subtype of the derived type.
-
- 34.a Proof: This happens when the parent subtype is constrained to a
- range that does not overlap with the range of a subtype of the parent
- type that appears in the profile of some primitive subprogram of the
- parent type. For example:
-
- 34.b type T1 is range 1..100;
- subtype S1 is T1 range 1..10;
- procedure P(X : in S1); -- P is a primitive subprogram
- type T2 is new T1 range 11..20;
- -- implicitly declared:
- -- procedure P(X : in T2'Base range 1..10);
- -- X cannot be in T2'First .. T2'Last
-
- 35 (17) If the reserved word abstract is given in the declaration of a
- type, the type is abstract (see 3.9.3).
-
-
- Examples
-
- 36 Examples of derived type declarations:
-
- 37 type Local_Coordinate is new Coordinate; -- two different types
- type Midweek is new Day range Tue .. Thu; -- see 3.5.1
- type Counter is new Positive; -- same range as Positive
-
- 38 type Special_Key is new Key_Manager.Key; -- see 7.3.1
- -- the inherited subprograms have the following specifications:
- -- procedure Get_Key(K : out Special_Key);
- -- function "<"(X,Y : Special_Key) return Boolean;
-
-
- Inconsistencies With Ada 83
-
- 38.a {inconsistencies with Ada 83} When deriving from a
- (nonprivate, nonderived) type in the same visible part in which it is
- defined, if a predefined operator had been overridden prior to the
- derivation, the derived type will inherit the user-defined operator
- rather than the predefined operator. The work-around (if the new
- behavior is not the desired behavior) is to move the definition of
- the derived type prior to the overriding of any predefined operators.
-
- Incompatibilities With Ada 83
-
- 38.b {incompatibilities with Ada 83} When deriving from a
- (nonprivate, nonderived) type in the same visible part in which it is
- defined, a primitive subprogram of the parent type declared before
- the derived type will be inherited by the derived type. This can
- cause upward incompatibilities in cases like this:
-
- 38.c package P is
- type T is (A, B, C, D);
- function F( X : T := A ) return Integer;
- type NT is new T;
- -- inherits F as
- -- function F( X : NT := A ) return Integer;
- -- in Ada 9X only
- ...
- end P;
- ...
- use P; -- Only one declaration of F from P is use-visible in
- -- Ada 83; two declarations of F are use-visible in
- -- Ada 9X.
- begin
- ...
- if F > 1 then ... -- legal in Ada 83, ambiguous in Ada 9X
-
- Extensions to Ada 83
-
- 38.d {extensions to Ada 83} The syntax for a derived_type_
- definition is amended to include an optional record_extension_part
- (see 3.9.1).
-
- 38.e A derived type may override the discriminants of the parent by
- giving a new discriminant_part. {94-4535.a}
-
- 38.f The parent type in a derived_type_definition may be a derived
- type defined in the same visible part.
-
- 38.g When deriving from a type in the same visible part in which it
- is defined, the primitive subprograms declared prior to the
- derivation are inherited as primitive subprograms of the derived
- type. See 3.2.3.
-
- Wording Changes From Ada 83
-
- 38.h We now talk about the classes to which a type belongs, rather
- than a single class.
-
- 38.i As explained in Section 13, the concept of "storage pool"
- replaces the Ada 83 concept of "collection." These concepts are
- similar, but not the same.
-
-
-
- 3.4.1 Derivation Classes
-
- 1 In addition to the various language-defined classes of types, types can
- be grouped into derivation classes.
-
-
- Static Semantics
-
- 2 {derived from (directly or indirectly)} A derived type is derived from
- its parent type directly; it is derived indirectly from any type from which
- its parent type is derived. {derivation class (for a type)} {root type (of a
- class)} {rooted at a type} The derivation class of types for a type T (also
- called the class rooted at T) is the set consisting of T (the root type of
- the class) and all types derived from T (directly or indirectly) plus any
- associated universal or class-wide types (defined below).
-
- 2.a Discussion: Note that the definition of ``derived from'' is a
- recursive definition. We don't define a root type for all
- interesting language-defined classes, though presumably we could.
-
- 2.b To be honest: By the class-wide type ``associated'' with a
- type T, we mean the type T'Class. Similarly, the universal type
- associated with root_integer, root_real, and root_fixed are
- universal_integer, universal_real, and universal_fixed, respectively.
-
- 3 Every type is either a specific type, a class-wide type, or a universal
- type. {specific type} A specific type is one defined by a type_declaration,
- a formal_type_declaration, or a full type definition embedded in a
- declaration for an object. Class-wide and universal types are implicitly
- defined, to act as representatives for an entire class of types, as follows:
-
- 3.a To be honest: The root types root_integer, root_real, and
- root_fixed are also specific types. They are declared in the
- specification of package Standard.
-
- 4 {class-wide type} Class-wide types
- Class-wide types are defined for [(and belong to)] each
- derivation class rooted at a tagged type (see 3.9). Given a
- subtype S of a tagged type T, S'Class is the subtype_mark for
- a corresponding subtype of the tagged class-wide type
- T'Class. Such types are called ``class-wide'' because when a
- formal parameter is defined to be of a class-wide type
- T'Class, an actual parameter of any type in the derivation
- class rooted at T is acceptable (see 8.6).
-
- 5 {first subtype} The set of values for a class-wide type
- T'Class is the discriminated union of the set of values of
- each specific type in the derivation class rooted at T (the
- tag acts as the implicit discriminant -- see 3.9).
- Class-wide types have no primitive subprograms of their own.
- However, as explained in 3.9.2, operands of a class-wide type
- T'Class can be used as part of a dispatching call on a
- primitive subprogram of the type T. The only components
- [(including discriminants)] of T'Class that are visible are
- those of T. If S is a first subtype, then S'Class is a first
- subtype.
-
- 5.a Reason: We want S'Class to be a first subtype when S is, so
- that an attribute_definition_clause like ``for S'Class'Output use
- ...;'' will be legal.
-
- 6 {universal type} Universal types
- Universal types are defined for [(and belong to)] the
- integer, real, and fixed point classes, and are referred to
- in this standard as respectively, universal_integer,
- universal_real, and universal_fixed. These are analogous to
- class-wide types for these language-defined numeric classes.
- As with class-wide types, if a formal parameter is of a
- universal type, then an actual parameter of any type in the
- corresponding class is acceptable. In addition, a value of a
- universal type (including an integer or real numeric_literal)
- is ``universal'' in that it is acceptable where some
- particular type in the class is expected (see 8.6).
-
- 7 The set of values of a universal type is the
- undiscriminated union of the set of values possible for any
- definable type in the associated class. Like class-wide
- types, universal types have no primitive subprograms of their
- own. However, their ``universality'' allows them to be used
- as operands with the primitive subprograms of any type in the
- corresponding class.
-
- 7.a Discussion: A class-wide type is only class-wide in one
- direction, from specific to class-wide, whereas a universal type is
- class-wide (universal) in both directions, from specific to universal
- and back.
-
- 7.b We considered defining class-wide or perhaps universal types
- for all derivation classes, not just tagged classes and these three
- numeric classes. However, this was felt to overly weaken the
- strong-typing model in some situations. Tagged types preserve strong
- type distinctions thanks to the run-time tag. Class-wide or
- universal types for untagged types would weaken the compile-time type
- distinctions without providing a compensating run-time-checkable
- distinction.
-
- 7.c We considered defining standard names for the universal numeric
- types so they could be used in formal parameter specifications.
- However, this was felt to impose an undue implementation burden for
- some implementations.
-
- 7.d To be honest: Formally, the set of values of a universal type
- is actually a copy of the undiscriminated union of the values of the
- types in its class. This is because we want each value to have
- exactly one type, with explicit or implicit conversion needed to go
- between types. An alternative, consistent model would be to
- associate a class, rather than a particular type, with a value, even
- though any given expression would have a particular type. In that
- case, implicit type conversions would not generally need to change
- the value, although an associated subtype conversion might need to.
-
- 8 {root_integer [partial]} {root_real [partial]} The integer and real
- numeric classes each have a specific root type in addition to their universal
- type, named respectively root_integer and root_real.
-
- 9 {cover (a type)} A class-wide or universal type is said to cover all of
- the types in its class. A specific type covers only itself.
-
- 10 {descendant (of a type)} A specific type T2 is defined to be a
- descendant of a type T1 if T2 is the same as T1, or if T2 is derived
- (directly or indirectly) from T1. A class-wide type T2'Class is defined to
- be a descendant of type T1 if T2 is a descendant of T1. Similarly, the
- universal types are defined to be descendants of the root types of their
- classes. {ancestor (of a type)} If a type T2 is a descendant of a type T1,
- then T1 is called an ancestor of T2. {ultimate ancestor (of a type)}
- {ancestor (ultimate)} The ultimate ancestor of a type is the ancestor of the
- type that is not a descendant of any other type.
-
- 10.a Ramification: A specific type is a descendant of itself.
- Class-wide types are considered descendants of the corresponding
- specific type, and do not have any descendants of their own.
-
- 10.b A specific type is an ancestor of itself. The root of a
- derivation class is an ancestor of all types in the class, including
- any class-wide types in the class.
-
- 10.c Discussion: The terms root, parent, ancestor, and ultimate
- ancestor are all related. For example:
-
- 10.d Each type has at most one parent, and one or more
- ancestor types; each type has exactly one ultimate
- ancestor. In Ada 83, the term ``parent type'' was
- sometimes used more generally to include any ancestor
- type (e.g. RM83-9.4(14)). In Ada 9X, we restrict parent
- to mean the immediate ancestor.
-
- 10.e A class of types has at most one root type; a derivation
- class has exactly one root type.
-
- 10.f The root of a class is an ancestor of all of the types in
- the class (including itself).
-
- 10.g The type root_integer is the root of the integer class,
- and is the ultimate ancestor of all integer types. A
- similar statement applies to root_real.
-
- 11 {inherited (from an ancestor type)} An inherited component [(including
- an inherited discriminant)] of a derived type is inherited from a given
- ancestor of the type if the corresponding component was inherited by each
- derived type in the chain of derivations going back to the given ancestor.
-
-
- NOTES
- 12 (18) Because operands of a universal type are acceptable to the
- predefined operators of any type in their class, ambiguity can result.
- For universal_integer and universal_real, this potential ambiguity is
- resolved by giving a preference (see 8.6) to the predefined operators of
- the corresponding root types (root_integer and root_real, respectively).
- Hence, in an apparently ambiguous expression like
-
- 13 1 + 4 < 7
-
- 14 where each of the literals is of type universal_integer, the
- predefined operators of root_integer will be preferred over those of
- other specific integer types, thereby resolving the ambiguity.
-
- 14.a Ramification: Except for this preference, a root numeric type
- is essentially like any other specific type in the associated numeric
- class. In particular, the result of a predefined operator of a root
- numeric type is not ``universal'' (implicitly convertible) even if
- both operands were.
-
-
-
- 3.5 Scalar Types
-
- 1 {scalar type} Scalar types comprise enumeration types, integer types, and
- real types. {discrete type} Enumeration types and integer types are called
- discrete types; {position number} each value of a discrete type has a
- position number which is an integer value. {numeric type} Integer types and
- real types are called numeric types. [All scalar types are ordered, that is,
- all relational operators are predefined for their values.]
-
-
- Syntax
-
- 2 range_constraint ::= range range
-
- 3 range ::= range_attribute_reference
- | simple_expression .. simple_expression
-
-
- 3.a Discussion: These need to be simple_expressions rather than
- more general expressions because ranges appear in membership tests
- and other contexts where expression .. expression would be ambiguous.
-
- 4 {range} {lower bound (of a range)} {upper bound (of a range)} {type of a
- range} A range has a lower bound and an upper bound and specifies a subset of
- the values of some scalar type (the type of the range). A range with lower
- bound L and upper bound R is described by ``L .. R''. {null range} If R is
- less than L, then the range is a null range, and specifies an empty set of
- values. Otherwise, the range specifies the values of the type from the lower
- bound to the upper bound, inclusive. {belong (to a range)} A value belongs
- to a range if it is of the type of the range, and is in the subset of values
- specified by the range. {satisfies [a range constraint]} A value satisfies a
- range constraint if it belongs to the associated range. {included (one range
- in another)} One range is included in another if all values that belong to
- the first range also belong to the second.
-
-
- Name Resolution Rules
-
- 5 {expected type [range_constraint range]} For a subtype_indication
- containing a range_constraint, either directly or as part of some other
- scalar_constraint, the type of the range shall resolve to that of the type
- determined by the subtype_mark of the subtype_indication. {expected type
- [range simple_expressions]} For a range of a given type, the simple_
- expressions of the range (likewise, the simple_expressions of the equivalent
- range for a range_attribute_reference) are expected to be of the type of the
- range.
-
- 5.a Discussion: In Ada 9X, constraints only appear within subtype_
- indications; things that look like constraints that appear in type
- declarations are called something else like range_specifications.
-
- 5.b We say "the expected type is ..." or "the type is expected to
- be ..." depending on which reads better. They are fundamentally
- equivalent, and both feed into the type resolution rules of clause
- 8.6.
-
- 5.c In some cases, it doesn't work to use expected types. For
- example, in the above rule, we say that the ``type of the range shall
- resolve to ...'' rather than ``the expected type for the range is
- ...''. We then use ``expected type'' for the bounds. If we used
- ``expected'' at both points, there would be an ambiguity, since one
- could apply the rules of 8.6 either on determining the type of the
- range, or on determining the types of the individual bounds. It is
- clearly important to allow one bound to be of a universal type, and
- the other of a specific type, so we need to use ``expected type'' for
- the bounds. Hence, we used ``shall resolve to'' for the type of the
- range as a whole. There are other situations where ``expected type''
- is not quite right, and we use ``shall resolve to'' instead.
-
-
- Static Semantics
-
- 6 {base range (of a scalar type) [distributed]} The base range of a scalar
- type is the range of finite values of the type that can be represented in
- every unconstrained object of the type; it is also the range supported at a
- minimum for intermediate values during the evaluation of expressions
- involving predefined operators of the type.
-
- 6.a Implementation Note: Note that in some machine architectures
- intermediates in an expression (particularly if static), and
- register-resident variables might accommodate a wider range. The
- base range does not include the values of this wider range that are
- not assignable without overflow to memory-resident objects.
-
- 6.b Ramification: {base range [of an enumeration type]} The base
- range of an enumeration type is the range of values of the
- enumeration type.
-
- 6.c Reason: If the representation supports infinities, the base
- range is nevertheless restricted to include only the representable
- finite values, so that 'Base'First and 'Base'Last are always
- guaranteed to be finite.
-
- 6.d To be honest: By a "value that can be assigned without
- overflow" we don't mean to restrict ourselves to values that can be
- represented exactly. Values between machine representable values can
- be assigned, but on subsequent reading, a slightly different value
- might be retrieved, as (partially) determined by the number of digits
- of precision of the type.
-
- 7 {constrained (subtype)} {unconstrained (subtype)} [A constrained scalar
- subtype is one to which a range constraint applies.] {range (of a scalar
- subtype)} The range of a constrained scalar subtype is the range associated
- with the range constraint of the subtype. The range of an unconstrained
- scalar subtype is the base range of its type.
-
-
- Dynamic Semantics
-
- 8 {compatibility [range with a scalar subtype]} A range is compatible with
- a scalar subtype if and only if it is either a null range or each bound of
- the range belongs to the range of the subtype. {compatibility [range_
- constraint with a scalar subtype]} A range_constraint is compatible with a
- scalar subtype if and only if its range is compatible with the subtype.
-
- 8.a Ramification: Only range_constraints (explicit or implicit)
- impose conditions on the values of a scalar subtype. The other
- scalar_constraints, digit_constraints and delta_constraints impose
- conditions on the subtype denoted by the subtype_mark in a subtype_
- indication, but don't impose a condition on the values of the subtype
- being defined. Therefore, a scalar subtype is not called constrained
- if all that applies to it is a digits_constraint. Decimal subtypes
- are subtle, because a digits_constraint without a range_constraint
- nevertheless includes an implicit range_constraint.
-
- 9 {elaboration [range_constraint]} The elaboration of a range_constraint
- consists of the evaluation of the range. {evaluation [range]} The evaluation
- of a range determines a lower bound and an upper bound. If simple_
- expressions are given to specify bounds, the evaluation of the range
- evaluates these simple_expressions in an arbitrary order, and converts them
- to the type of the range. {implicit subtype conversion [bounds of a range]}
- If a range_attribute_reference is given, the evaluation of the range consists
- of the evaluation of the range_attribute_reference.
-
- 10 Attributes
-
- 11 For every scalar subtype S, the following attributes are defined:
-
- 12 S'First
- S'First denotes the lower bound of the range of S. The value
- of this attribute is of the type of S.
-
- 12.a Ramification: Evaluating S'First never raises Constraint_Error.
-
- 13 S'Last
- S'Last denotes the upper bound of the range of S. The value
- of this attribute is of the type of S.
-
- 13.a Ramification: Evaluating S'Last never raises Constraint_Error.
-
- 14 S'Range
- S'Range is equivalent to the range S'First .. S'Last.
-
- 15 {base subtype (of a type)} S'Base
- S'Base denotes an unconstrained subtype of the type of
- S. This unconstrained subtype is called the base subtype of
- the type.
-
- 16 S'Min
- S'Min denotes a function with the following specification:
-
- 17 function S'Min(Left, Right : S'Base)
- return S'Base
-
- 18 The function returns the lesser of the values of the two
- parameters.
-
- 18.a Discussion: {italics (formal parameters of attribute functions)} The
- formal parameter names are italicized because they cannot be used in
- calls -- see 6.4. Such a specification cannot be written by the user
- because an attribute_reference is not permitted as the designator of
- a user-defined function, nor can its formal parameters be anonymous.
-
- 19 S'Max
- S'Max denotes a function with the following specification:
-
- 20 function S'Max(Left, Right : S'Base)
- return S'Base
-
- 21 The function returns the greater of the values of the
- two parameters.
-
- 22 S'Succ
- S'Succ denotes a function with the following specification:
-
- 23 function S'Succ(Arg : S'Base)
- return S'Base
-
- 24 {Constraint_Error (raised by failure of run-time check)}
- For an enumeration type, the function returns the value whose
- position number is one more than that of the value of Arg;
- {Range_Check [partial]} {check, language-defined (Range_
- Check)} Constraint_Error is raised if there is no such value
- of the type. For an integer type, the function returns the
- result of adding one to the value of Arg. For a fixed point
- type, the function returns the result of adding small to the
- value of Arg. For a floating point type, the function
- returns the machine number (as defined in 3.5.7) immediately
- above the value of Arg; {Range_Check [partial]} {check,
- language-defined (Range_Check)} Constraint_Error is raised if
- there is no such machine number.
-
- 24.a Ramification: S'Succ for a modular integer subtype wraps around if
- the value of Arg is S'Base'Last. S'Succ for a signed integer subtype
- might raise Constraint_Error if the value of Arg is S'Base'Last, or
- it might return the out-of-base-range value S'Base'Last+1, as is
- permitted for all predefined numeric operations.
-
- 25 S'Pred
- S'Pred denotes a function with the following specification:
-
- 26 function S'Pred(Arg : S'Base)
- return S'Base
-
- 27 {Constraint_Error (raised by failure of run-time check)}
- For an enumeration type, the function returns the value whose
- position number is one less than that of the value of Arg;
- {Range_Check [partial]} {check, language-defined (Range_
- Check)} Constraint_Error is raised if there is no such value
- of the type. For an integer type, the function returns the
- result of subtracting one from the value of Arg. For a fixed
- point type, the function returns the result of subtracting
- small from the value of Arg. For a floating point type, the
- function returns the machine number (as defined in 3.5.7)
- immediately below the value of Arg; {Range_Check [partial]}
- {check, language-defined (Range_Check)} Constraint_Error is
- raised if there is no such machine number.
-
- 27.a Ramification: S'Pred for a modular integer subtype wraps around if
- the value of Arg is S'Base'First. S'Pred for a signed integer
- subtype might raise Constraint_Error if the value of Arg is
- S'Base'First, or it might return the out-of-base-range value
- S'Base'First-1, as is permitted for all predefined numeric
- operations.
-
- 28 S'Wide_Image
- S'Wide_Image denotes a function with the following
- specification:
-
- 29 function S'Wide_Image(Arg : S'Base)
- return Wide_String
-
- 30 {image (of a value)} The function returns an image of
- the value of Arg, that is, a sequence of characters
- representing the value in display form. The lower bound of
- the result is one.
-
- 31 The image of an integer value is the corresponding
- decimal literal, without underlines, leading zeros, exponent,
- or trailing spaces, but with a single leading character that
- is either a minus sign or a space.
-
- 31.a Implementation Note: If the machine supports negative zeros
- for signed integer types, it is not specified whether "-0" or " 0"
- should be returned for negative zero. We don't have enough
- experience with such machines to know what is appropriate, and what
- other languages do. In any case, the implementation should be
- consistent.
-
- 32 {nongraphic character} The image of an enumeration value
- is either the corresponding identifier in upper case or the
- corresponding character literal (including the two
- apostrophes); neither leading nor trailing spaces are
- included. For a nongraphic character (a value of a character
- type that has no enumeration literal associated with it), the
- result is a corresponding language-defined or implementation-
- defined name in upper case (for example, the image of the
- nongraphic character identified as nul is ``NUL'' -- the
- quotes are not part of the image).
-
- 32.a Implementation Note: For an enumeration type T that has
- ``holes'' (caused by an enumeration_representation_clause), {Program_
- Error (raised by failure of run-time check)} T'Wide_Image should
- raise Program_Error if the value is one of the holes (which is a
- bounded error anyway, since holes can be generated only via
- uninitialized variables and similar things.
-
- 33 The image of a floating point value is a decimal real
- literal best approximating the value (rounded away from zero
- if halfway between) with a single leading character that is
- either a minus sign or a space, a single digit (that is
- nonzero unless the value is zero), a decimal point,
- S'Digits-1 (see 3.5.8) digits after the decimal point (but
- one if S'Digits is one), an upper case E, the sign of the
- exponent (either + or -), and two or more digits (with
- leading zeros if necessary) representing the exponent. If
- S'Signed_Zeros is True, then the leading character is a minus
- sign for a negatively signed zero. {94-4526.b}
-
- 33.a To be honest: Leading zeros are present in the exponent only
- if necessary to make the exponent at least two digits.
-
- 33.b Reason: This image is intended to conform to that produced by
- Text_IO.Float_IO.Put in its default format.
-
- 33.c Implementation Note: The rounding direction is specified here
- to ensure portability of output results.
-
- 34 The image of a fixed point value is a decimal real
- literal best approximating the value (rounded away from zero
- if halfway between) with a single leading character that is
- either a minus sign or a space, one or more digits before the
- decimal point (with no redundant leading zeros), a decimal
- point, and S'Aft (see 3.5.10) digits after the decimal point.
-
- 34.a Reason: This image is intended to conform to that produced by
- Text_IO.Fixed_IO.Put.
-
- 34.b Implementation Note: The rounding direction is specified here
- to ensure portability of output results.
-
- 34.c Implementation Note: For a machine that supports negative
- zeros, it is not specified whether "-0.000" or " 0.000" is returned.
- See corresponding comment above about integer types with signed
- zeros.
-
- 35 S'Image
- S'Image denotes a function with the following specification:
-
- 36 function S'Image(Arg : S'Base)
- return String
-
- 37 The function returns an image of the value of Arg as a
- String. The lower bound of the result is one. The image has
- the same sequence of graphic characters as that defined for
- S'Wide_Image if all the graphic characters are defined in
- Character; otherwise the sequence of characters is
- implementation defined (but no shorter than that of S'Wide_
- Image for the same value of Arg).
-
- 37.a Implementation defined: The sequence of characters of the
- value returned by S'Image when some of the graphic characters of
- S'Wide_Image are not defined in Character.
-
- 38 S'Wide_Width
- S'Wide_Width denotes the maximum length of a Wide_String
- returned by S'Wide_Image over all values of the subtype S. It
- denotes zero for a subtype that has a null range. Its type
- is universal_integer.
-
- 38.a Change: Added Wide_Width attribute as per WG9 resolution.
-
- 39 S'Width
- S'Width denotes the maximum length of a String returned by
- S'Image over all values of the subtype S. It denotes zero for
- a subtype that has a null range. Its type is universal_
- integer.
-
- 40 S'Wide_Value
- S'Wide_Value denotes a function with the following
- specification:
-
- 41 function S'Wide_Value(Arg : Wide_String)
- return S'Base
-
- 42 This function returns a value given an image of the
- value as a Wide_String, ignoring any leading or trailing
- spaces.
-
- 43 {evaluation [Wide_Value]} {Constraint_Error (raised by
- failure of run-time check)} For the evaluation of a call on
- S'Wide_Value for an enumeration subtype S, if the sequence of
- characters of the parameter (ignoring leading and trailing
- spaces) has the syntax of an enumeration literal and if it
- corresponds to a literal of the type of S (or corresponds to
- the result of S'Wide_Image for a nongraphic character of the
- type), the result is the corresponding enumeration value;
- {Range_Check [partial]} {check, language-defined (Range_
- Check)} otherwise Constraint_Error is raised.
-
- 43.a Discussion: It's not crystal clear that Range_Check is
- appropriate here, but it doesn't seem worthwhile to invent a whole
- new check name just for this weird case, so we decided to lump it in
- with Range_Check.
-
- 44 {Constraint_Error (raised by failure of run-time check)}
- For the evaluation of a call on S'Wide_Value (or S'Value) for
- an integer subtype S, if the sequence of characters of the
- parameter (ignoring leading and trailing spaces) has the
- syntax of an integer literal, with an optional leading sign
- character (plus or minus for a signed type; only plus for a
- modular type), and the corresponding numeric value belongs to
- the base range of the type of S, then that value is the
- result; {Range_Check [partial]} {check, language-defined
- (Range_Check)} otherwise Constraint_Error is raised.
-
- 44.a Change: Changed the syntax accepted by Wide_Value for modular
- types to match Modular_IO.Get; the intent is that these be the same.
- In particular, the number can have a plus sign or no sign; it cannot
- have a minus sign.
-
- 44.b Discussion: We considered allowing 'Value to return a
- representable but out-of-range value without a Constraint_Error.
- However, we currently require (see 4.9) in an assignment_statement
- like "X := <numeric_literal>;" that the value of the numeric-literal
- be in X's base range (at compile time), so it seems unfriendly and
- confusing to have a different range allowed for 'Value. Furthermore,
- for modular types, without the requirement for being in the base
- range, 'Value would have to handle arbitrarily long literals (since
- overflow never occurs for modular types).
-
- 45 For the evaluation of a call on S'Wide_Value (or
- S'Value) for a real subtype S, if the sequence of characters
- of the parameter (ignoring leading and trailing spaces) has
- the syntax of one of the following:
-
- 46 numeric_literal
-
- 47 numeral.[exponent]
-
- 48 .numeral[exponent]
-
- 49 base#based_numeral.#[exponent]
-
- 50 base#.based_numeral#[exponent]
-
- 51 {Constraint_Error (raised by failure of run-time check)}
- with an optional leading sign character (plus or minus), and
- if the corresponding numeric value belongs to the base range
- of the type of S, then that value is the result; {Range_Check
- [partial]} {check, language-defined (Range_Check)} otherwise
- Constraint_Error is raised. The sign of a zero value is
- preserved (positive if none has been specified) if S'Signed_
- Zeros is True. {94-4526.b}
-
- 52 S'Value
- S'Value denotes a function with the following specification:
-
- 53 function S'Value(Arg : String)
- return S'Base
-
- 54 This function returns a value given an image of the
- value as a String, ignoring any leading or trailing spaces.
-
- 55 {evaluation [Value]} {Constraint_Error (raised by
- failure of run-time check)} For the evaluation of a call on
- S'Value for an enumeration subtype S, if the sequence of
- characters of the parameter (ignoring leading and trailing
- spaces) has the syntax of an enumeration literal and if it
- corresponds to a literal of the type of S (or corresponds to
- the result of S'Image for a value of the type), the result is
- the corresponding enumeration value; {Range_Check [partial]}
- {check, language-defined (Range_Check)} otherwise Constraint_
- Error is raised. For a numeric subtype S, the evaluation of
- a call on S'Value with Arg of type String is equivalent to a
- call on S'Wide_Value for a corresponding Arg of type Wide_
- String.
-
- 55.a Reason: S'Value is subtly different from S'Wide_Value for
- enumeration subtypes since S'Image might produce a different sequence
- of characters than S'Wide_Image if the enumeration literal uses
- characters outside of the predefined type Character. That is why we
- don't just define S'Value in terms of S'Wide_Value for enumeration
- subtypes. S'Value and S'Wide_Value for numeric subtypes yield the
- same result given the same sequence of characters.
-
-
- Implementation Permissions
-
- 56 An implementation may extend the Wide_Value, [Value, Wide_Image, and
- Image] attributes of a floating point type to support special values such as
- infinities and NaNs. {94-4526.c} {94-4893.d} {94-4901.a}
-
- 56.a Proof: The permission is really only necessary for Wide_
- Value, because Value is defined in terms of Wide_Value, and because
- the behavior of Wide_Image and Image is already unspecified for
- things like infinities and NaNs.
-
- 56.b Reason: This is to allow implementations to define full
- support for IEEE arithmetic. See also the similar permission for Get
- in A.10.9.
-
-
- NOTES
- 57 (19) The evaluation of S'First or S'Last never raises an exception. If
- a scalar subtype S has a nonnull range, S'First and S'Last belong to
- this range. These values can, for example, always be assigned to a
- variable of subtype S.
-
- 57.a Discussion: This paragraph addresses an issue that came up with
- Ada 83, where for fixed point types, the end points of the range
- specified in the type definition were not necessarily within the base
- range of the type. However, it was later clarified (and we reconfirm
- it in 3.5.9, ``Fixed Point Types'') that the First and Last
- attributes reflect the true bounds chosen for the type, not the
- bounds specified in the type definition (which might be outside the
- ultimately chosen base range).
-
- 58 (20) For a subtype of a scalar type, the result delivered by the
- attributes Succ, Pred, and Value might not belong to the subtype;
- similarly, the actual parameters of the attributes Succ, Pred, and Image
- need not belong to the subtype.
-
- 59 (21) For any value V (including any nongraphic character) of an
- enumeration subtype S, S'Value(S'Image(V)) equals V, as does S'Wide_
- Value(S'Wide_Image(V)). Neither expression ever raises Constraint_
- Error.
-
-
- Examples
-
- 60 Examples of ranges:
-
- 61 -10 .. 10
- X .. X + 1
- 0.0 .. 2.0*Pi
- Red .. Green -- see 3.5.1
- 1 .. 0 -- a null range
- Table'Range -- a range attribute reference (see 3.6)
-
- 62 Examples of range constraints:
-
- 63 range -999.0 .. +999.0
- range S'First+1 .. S'Last-1
-
-
- Incompatibilities With Ada 83
-
- 63.a {incompatibilities with Ada 83} S'Base is no longer defined
- for nonscalar types. One conceivable existing use of S'Base for
- nonscalar types is S'Base'Size where S is a generic formal private
- type. However, that is not generally useful because the actual
- subtype corresponding to S might be a constrained array or
- discriminated type, which would mean that S'Base'Size might very well
- overflow (for example, S'Base'Size where S is a constrained subtype
- of String will generally be 8 * (Integer'Last + 1)). For derived
- discriminated types that are packed, S'Base'Size might not even be
- well defined if the first subtype is constrained, thereby allowing
- some amount of normally required ``dope'' to have been squeezed out
- in the packing. Hence our conclusion is that S'Base'Size is not
- generally useful in a generic, and does not justify keeping the
- attribute Base for nonscalar types just so it can be used as a
- prefix.
-
- Extensions to Ada 83
-
- 63.b {extensions to Ada 83} The attribute S'Base for a scalar
- subtype is now permitted anywhere a subtype_mark is permitted.
- S'Base'First .. S'Base'Last is the base range of the type. Using an
- attribute_definition_clause, one cannot specify any subtype-specific
- attributes for the subtype denoted by S'Base (the base subtype).
-
- 63.c The attribute S'Range is now allowed for scalar subtypes.
-
- 63.d The attributes S'Min and S'Max are now defined, and made
- available for all scalar types.
-
- 63.e The attributes S'Succ, S'Pred, S'Image, S'Value, and S'Width
- are now defined for real types as well as discrete types.
-
- 63.f Wide_String versions of S'Image and S'Value are defined.
- These are called S'Wide_Image and S'Wide_Value to avoid introducing
- ambiguities involving uses of these attributes with string literals.
-
- Wording Changes From Ada 83
-
- 63.g We now use the syntactic category range_attribute_reference
- since it is now syntactically distinguished from other attribute
- references.
-
- 63.h The definition of S'Base has been moved here from 3.3.3 since
- it now applies only to scalar types.
-
- 63.i More explicit rules are provided for nongraphic characters.
-
-
-
- 3.5.1 Enumeration Types
-
- 1 [{enumeration type} An enumeration_type_definition defines an enumeration
- type.]
-
-
- Syntax
-
- 2 enumeration_type_definition ::=
- (enumeration_literal_specification {, enumeration_literal_specification})
-
- 3 enumeration_literal_specification ::= defining_identifier | defining_chara\
- cter_literal
-
- 4 defining_character_literal ::= character_literal
-
-
- Legality Rules
-
- 5 [The defining_identifiers and defining_character_literals listed in an
- enumeration_type_definition shall be distinct.]
-
- 5.a Proof: This is a ramification of the normal disallowance of
- homographs explicitly declared immediately in the same declarative
- region.
-
-
- Static Semantics
- 6 {enumeration literal} Each enumeration_literal_specification is the
- explicit declaration of the corresponding enumeration literal: it declares a
- parameterless function, whose defining name is the defining_identifier or
- defining_character_literal, and whose result type is the enumeration type.
-
- 6.a Reason: This rule defines the profile of the enumeration
- literal, which is used in the various types of conformance.
-
- 6.b Ramification: The parameterless function associated with an
- enumeration literal is fully defined by the enumeration_type_
- definition; a body is not permitted for it, and it never fails the
- Elaboration_Check when called.
-
- 7 Each enumeration literal corresponds to a distinct value of the
- enumeration type, and to a distinct position number. {position number [of an
- enumeration value]} The position number of the value of the first listed
- enumeration literal is zero; the position number of the value of each
- subsequent enumeration literal is one more than that of its predecessor in
- the list.
-
- 8 [The predefined order relations between values of the enumeration type
- follow the order of corresponding position numbers.]
-
- 9 [{overloaded [enumeration literal]} If the same defining_identifier or
- defining_character_literal is specified in more than one enumeration_type_
- definition, the corresponding enumeration literals are said to be overloaded.
- At any place where an overloaded enumeration literal occurs in the text of a
- program, the type of the enumeration literal has to be determinable from the
- context (see 8.6).]
-
-
- Dynamic Semantics
-
- 10 {elaboration [enumeration_type_definition]} {constrained (subtype)}
- {unconstrained (subtype)} The elaboration of an enumeration_type_definition
- creates the enumeration type and its first subtype, which is constrained to
- the base range of the type.
-
- 10.a Ramification: The first subtype of a discrete type is always
- constrained, except in the case of a derived type whose parent
- subtype is Whatever'Base.
-
- 11 When called, the parameterless function associated with an enumeration
- literal returns the corresponding value of the enumeration type.
-
-
- NOTES
- 12 (22) If an enumeration literal occurs in a context that does not
- otherwise suffice to determine the type of the literal, then
- qualification by the name of the enumeration type is one way to resolve
- the ambiguity (see 4.7).
-
-
- Examples
-
- 13 Examples of enumeration types and subtypes:
-
- 14 type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
- type Suit is (Clubs, Diamonds, Hearts, Spades);
- type Gender is (M, F);
- type Level is (Low, Medium, Urgent);
- type Color is (White, Red, Yellow, Green, Blue, Brown, Black);
- type Light is (Red, Amber, Green); -- Red and Green are overloaded
-
- 15 type Hexa is ('A', 'B', 'C', 'D', 'E', 'F');
- type Mixed is ('A', 'B', '*', B, None, '?', '%');
-
- 16 subtype Weekday is Day range Mon .. Fri;
- subtype Major is Suit range Hearts .. Spades;
- subtype Rainbow is Color range Red .. Blue; -- the Color Red, not the Lig\
- ht
-
-
- Wording Changes From Ada 83
-
- 16.a The syntax rule for defining_character_literal is new. It is
- used for the defining occurrence of a character_literal, analogously
- to defining_identifier. Usage occurrences use the name or selector_
- name syntactic categories.
-
- 16.b We emphasize the fact that an enumeration literal denotes a
- function, which is called to produce a value.
-
-
-
- 3.5.2 Character Types
-
- Static Semantics
-
- 1 {character type} An enumeration type is said to be a character type if at
- least one of its enumeration literals is a character_literal.
-
- 2 {Latin-1} {BMP} {ISO 10646} {Character} The predefined type Character is
- a character type whose values correspond to the 256 code positions of Row 00
- (also known as Latin-1) of the ISO 10646 Basic Multilingual Plane (BMP).
- Each of the graphic characters of Row 00 of the BMP has a corresponding
- character_literal in Character. Each of the nongraphic positions of Row 00
- (0000-001F and 007F-009F) has a corresponding language-defined name, which is
- not usable as an enumeration literal, but which is usable with the attributes
- (Wide_)Image and (Wide_)Value; these names are given in the definition of
- type Character in A.1, ``The Package Standard'', but are set in italics.
- {italics (nongraphic characters)}
-
- 3 {Wide_Character} {BMP} {ISO 10646} The predefined type Wide_Character is
- a character type whose values correspond to the 65536 code positions of the
- ISO 10646 Basic Multilingual Plane (BMP). Each of the graphic characters of
- the BMP has a corresponding character_literal in Wide_Character. The first
- 256 values of Wide_Character have the same character_literal or
- language-defined name as defined for Character. The last 2 values of Wide_
- Character correspond to the nongraphic positions FFFE and FFFF of the BMP,
- and are assigned the language-defined names FFFE and FFFF. As with the other
- language-defined names for nongraphic characters, the names FFFE and FFFF are
- usable only with the attributes (Wide_)Image and (Wide_)Value; they are not
- usable as enumeration literals. All other values of Wide_Character are
- considered graphic characters, and have a corresponding character_literal.
-
- 3.a Reason: The language-defined names are not usable as
- enumeration literals to avoid "polluting" the name space. Since
- Wide_Character is defined in Standard, if the names FFFE and FFFF
- were usable as enumeration literals, they would hide other
- nonoverloadable declarations with the same names in use-d packages.
-
- 3.b ISO 10646 has not defined the meaning of all of the code
- positions from 0100 through FFFD, but they are all considered graphic
- characters by Ada to simplify the implementation, and to allow for
- revisions to ISO 10646. In ISO 10646, FFFE and FFFF are special, and
- will never be associated with graphic characters in any revision.
-
-
- Implementation Permissions
-
- 4 {localization} In a nonstandard mode, an implementation may provide other
- interpretations for the predefined types Character and Wide_Character[, to
- conform to local conventions].
-
-
- Implementation Advice
-
- 5 {localization} If an implementation supports a mode with alternative
- interpretations for Character and Wide_Character, the set of graphic
- characters of Character should nevertheless remain a proper subset of the set
- of graphic characters of Wide_Character. Any character set ``localizations''
- should be reflected in the results of the subprograms defined in the
- language-defined package Characters.Handling (see A.3) available in such a
- mode. In a mode with an alternative interpretation of Character, the
- implementation should also support a corresponding change in what is a legal
- identifier_letter.
-
-
- NOTES
- 6 (23) The language-defined library package Characters.Latin_1 (see A.3.3)
- includes the declaration of constants denoting control characters, lower
- case characters, and special characters of the predefined type
- Character.
-
- 6.a To be honest: The package ASCII does the same, but only for the
- first 128 characters of Character. Hence, it is an obsolescent
- package, and we no longer mention it here.
-
- 7 (24) A conventional character set such as EBCDIC can be declared as a
- character type; the internal codes of the characters can be specified by
- an enumeration_representation_clause as explained in clause 13.4.
-
-
- Examples
-
- 8 Example of a character type:
-
- 9 type Roman_Digit is ('I', 'V', 'X', 'L', 'C', 'D', 'M');
-
-
- Inconsistencies With Ada 83
-
- 9.a {inconsistencies with Ada 83} The declaration of Wide_Character
- in package Standard hides use-visible declarations with the same
- defining identifier. In the unlikely event that an Ada 83 program
- had depended on such a use-visible declaration, and the program
- remains legal after the substitution of Standard.Wide_Character, the
- meaning of the program will be different.
-
- Incompatibilities With Ada 83
-
- 9.b {incompatibilities with Ada 83} The presence of Wide_Character
- in package Standard means that an expression such as
-
- 9.c 'a' = 'b'
-
- 9.d is ambiguous in Ada 9X, whereas in Ada 83 both literals could
- be resolved to be of type Character.
-
- 9.e The change in visibility rules (see 4.2) for character literals
- means that additional qualification might be necessary to resolve
- expressions involving overloaded subprograms and character literals.
-
- Extensions to Ada 83
-
- 9.f {extensions to Ada 83} The type Character has been extended to
- have 256 positions, and the type Wide_Character has been added. Note
- that this change was already approved by the ARG for Ada 83
- conforming compilers.
-
- 9.g The rules for referencing character literals are changed (see
- 4.2), so that the declaration of the character type need not be
- directly visible to use its literals, similar to null and string
- literals. Context is used to resolve their type.
-
-
-
- 3.5.3 Boolean Types
-
- Static Semantics
-
- 1 {Boolean} There is a predefined enumeration type named Boolean, [declared
- in the visible part of package Standard]. {False} {True} It has the two
- enumeration literals False and True ordered with the relation False < True.
- {boolean type} Any descendant of the predefined type Boolean is called a
- boolean type.
-
- 1.a Implementation Note: An implementation is not required to
- support enumeration representation clauses on boolean types that
- impose an unacceptable implementation burden. See 13.4,
- ``Enumeration Representation Clauses''. However, it is generally
- straightforward to support representations where False is zero and
- True is 2**n - 1 for some n.
-
-
-
- 3.5.4 Integer Types
-
- 1 {integer type} {signed integer type} {modular type} An integer_type_
- definition defines an integer type; it defines either a signed integer type,
- or a modular integer type. The base range of a signed integer type includes
- at least the values of the specified range. A modular type is an integer
- type with all arithmetic modulo a specified positive modulus; such a type
- corresponds to an unsigned type with wrap-around semantics. {unsigned type:
- see modular type}
-
-
- Syntax
-
- 2 integer_type_definition ::= signed_integer_type_definition | modular_type_d\
- efinition
-
- 3 signed_integer_type_definition ::= range static_simple_expression .. static\
- _simple_expression
-
- 3.a Discussion: We don't call this a range_constraint, because it
- is rather different -- not only is it required to be static, but the
- associated overload resolution rules are different than for normal
- range constraints. A similar comment applies to real_range_
- specification. This used to be integer_range_specification but when
- we added support for modular types, it seemed overkill to have three
- levels of syntax rules, and just calling these signed_integer_range_
- specification and modular_range_specification loses the fact that
- they are defining different classes of types, which is important for
- the generic type matching rules.
-
- 4 modular_type_definition ::= mod static_expression
-
-
- Name Resolution Rules
-
- 5 {expected type [signed_integer_type_definition simple_expression]} Each
- simple_expression in a signed_integer_type_definition is expected to be of
- any integer type; they need not be of the same type. {expected type
- [modular_type_definition expression]} The expression in a modular_type_
- definition is likewise expected to be of any integer type.
-
-
- Legality Rules
-
- 6 The simple_expressions of a signed_integer_type_definition shall be
- static, and their values shall be in the range System.Min_Int .. System.Max_
- Int.
-
- 7 {modulus (of a modular type)} {Max_Binary_Modulus} {Max_Nonbinary_
- Modulus} The expression of a modular_type_definition shall be static, and its
- value (the modulus) shall be positive, and shall be no greater than
- System.Max_Binary_Modulus if a power of 2, or no greater than System.Max_
- Nonbinary_Modulus if not.
-
- 7.a Reason: For a 2's-complement machine, supporting nonbinary
- moduli greater than System.Max_Int can be quite difficult, whereas
- essentially any binary moduli are straightforward to support, up to
- 2*System.Max_Int+2, so this justifies having two separate limits.
-
-
- Static Semantics
-
- 8 The set of values for a signed integer type is the (infinite) set of
- mathematical integers[, though only values of the base range of the type are
- fully supported for run-time operations]. The set of values for a modular
- integer type are the values from 0 to one less than the modulus, inclusive.
-
- 9 {base range [of a signed integer type]} A signed_integer_type_definition
- defines an integer type whose base range includes at least the values of the
- simple_expressions and is symmetric about zero, excepting possibly an extra
- negative value. {constrained (subtype)} {unconstrained (subtype)} A signed_
- integer_type_definition also defines a constrained first subtype of the type,
- with a range whose bounds are given by the values of the simple_expressions,
- converted to the type being defined. {implicit subtype conversion [bounds of
- signed integer type]}
-
- 9.a Implementation Note: The base range of a signed integer type
- might be much larger than is necessary to satisfy the aboved
- requirements.
-
- 10 {base range [of a modular type]} A modular_type_definition defines a
- modular type whose base range is from zero to one less than the given
- modulus. {constrained (subtype)} {unconstrained (subtype)} A modular_type_
- definition also defines a constrained first subtype of the type with a range
- that is the same as the base range of the type.
-
- 11 {Integer} There is a predefined signed integer subtype named Integer[,
- declared in the visible part of package Standard]. It is constrained to the
- base range of its type.
-
- 11.a Reason: Integer is a constrained subtype, rather than an
- unconstrained subtype. This means that on assignment to an object of
- subtype Integer, a range check is required. On the other hand, an
- object of subtype Integer'Base is unconstrained, and no range check
- (only overflow check) is required on assignment. For example, if the
- object is held in an extended-length register, its value might be
- outside of Integer'First .. Integer'Last. All parameter and result
- subtypes of the predefined integer operators are of such
- unconstrained subtypes, allowing extended-length registers to be used
- as operands or for the result. In an earlier version of Ada 9X,
- Integer was unconstrained. However, the fact that certain
- Constraint_Errors might be omitted or appear elsewhere was felt to be
- an undesirable upward inconsistency in this case. Note that for
- Float, the opposite conclusion was reached, partly because of the
- high cost of performing range checks when not actually necessary.
- Objects of subtype Float are unconstrained, and no range checks, only
- overflow checks, are performed for them.
-
- 12 {Natural} {Positive} Integer has two predefined subtypes, [declared in
- the visible part of package Standard:]
-
- 13 subtype Natural is Integer range 0 .. Integer'Last;
- subtype Positive is Integer range 1 .. Integer'Last;
-
- 14 {root_integer} {Min_Int} {Max_Int} A type defined by an integer_type_
- definition is implicitly derived from root_integer, an anonymous predefined
- (specific) integer type, whose base range is System.Min_Int .. System.Max_
- Int. However, the base range of the new type is not inherited from root_
- integer, but is instead determined by the range or modulus specified by the
- integer_type_definition. {universal_integer [partial]} {integer literals}
- [Integer literals are all of the type universal_integer, the universal type
- (see 3.4.1) for the class rooted at root_integer, allowing their use with the
- operations of any integer type.]
-
- 14.a Discussion: This implicit derivation is not considered
- exactly equivalent to explicit derivation via a derived_type_
- definition. In particular, integer types defined via a derived_type_
- definition inherit their base range from their parent type. A type
- defined by an integer_type_definition does not necessarily inherit
- its base range from root_integer. It is not specified whether the
- implicit derivation from root_integer is direct or indirect, not that
- it really matters. All we want is for all integer types to be
- descendants of root_integer.
-
- 14.b Implementation Note: It is the intent that even nonstandard
- integer types (see below) will be descendants of root_integer, even
- though they might have a base range that exceeds that of root_
- integer. This causes no problem for static calculations, which are
- performed without range restrictions (see 4.9). However for run-time
- calculations, it is possible that Constraint_Error might be raised
- when using an operator of root_integer on the result of 'Val applied
- to a value of a nonstandard integer type.
-
- 15 {position number [of an integer value]} The position number of an
- integer value is equal to the value.
-
- 16 For every modular subtype S, the following attribute is defined:
-
- 17 S'Modulus
- S'Modulus yields the modulus of the type of S, as a value of
- the type universal_integer.
-
-
- Dynamic Semantics
-
- 18 {elaboration [integer_type_definition]} The elaboration of an integer_
- type_definition creates the integer type and its first subtype.
-
- 19 For a modular type, if the result of the execution of a predefined
- operator (see 4.5) is outside the base range of the type, the result is
- reduced modulo the modulus of the type to a value that is within the base
- range of the type.
-
- 20 {Overflow_Check [partial]} {check, language-defined (Overflow_Check)}
- {Constraint_Error (raised by failure of run-time check)} For a signed integer
- type, the exception Constraint_Error is raised by the execution of an
- operation that cannot deliver the correct result because it is outside the
- base range of the type.[{Division_Check [partial]} {check, language-defined
- (Division_Check)} {Constraint_Error (raised by failure of run-time check)}
- For any integer type, Constraint_Error is raised by the operators "/", "rem",
- and "mod" if the right operand is zero.]
- Implementation Requirements
-
- 21 {Integer} In an implementation, the range of Integer shall include the
- range -2**15+1 .. +2**15-1.
-
- 22 {Long_Integer} If Long_Integer is predefined for an implementation, then
- its range shall include the range -2**31+1 .. +2**31-1.
-
- 23 System.Max_Binary_Modulus shall be at least 2**16. {94-4776.b}
- {94-4789.a} {94-4790.a}
-
-
- Implementation Permissions
-
- 24 For the execution of a predefined operation of a signed integer type,
- the implementation need not raise Constraint_Error if the result is outside
- the base range of the type, so long as the correct result is produced.
-
- 24.a Discussion: Constraint_Error is never raised for operations
- on modular types, except for divide-by-zero (and rem/mod-by-zero).
-
- 25 {Long_Integer} {Short_Integer} An implementation may provide additional
- predefined signed integer types[, declared in the visible part of Standard],
- whose first subtypes have names of the form Short_Integer, Long_Integer,
- Short_Short_Integer, Long_Long_Integer, etc. Different predefined integer
- types are allowed to have the same base range. However, the range of Integer
- should be no wider than that of Long_Integer. Similarly, the range of Short_
- Integer (if provided) should be no wider than Integer. Corresponding
- recommendations apply to any other predefined integer types. There need not
- be a named integer type corresponding to each distinct base range supported
- by an implementation. The range of each first subtype should be the base
- range of its type.
-
- 25.a Implementation defined: The predefined integer types declared
- in Standard.
-
- 26 {nonstandard integer type} An implementation may provide nonstandard
- integer types, descendants of root_integer that are declared outside of the
- specification of package Standard, which need not have all the standard
- characteristics of a type defined by an integer_type_definition. For
- example, a nonstandard integer type might have an asymmetric base range or it
- might not be allowed as an array or loop index (a very long integer). Any
- type descended from a nonstandard integer type is also nonstandard. An
- implementation may place arbitrary restrictions on the use of such types; it
- is implementation defined whether operators that are predefined for ``any
- integer type'' are defined for a particular nonstandard integer type. [In
- any case, such types are not permitted as explicit_generic_actual_parameters
- for formal scalar types -- see 12.5.2.]
-
- 26.a Implementation defined: Any nonstandard integer types and the
- operators defined for them.
-
- 27 {one's complement [modular types]} For a one's complement machine, the
- high bound of the base range of a modular type whose modulus is one less than
- a power of 2 may be equal to the modulus, rather than one less than the
- modulus. It is implementation defined for which powers of 2, if any, this
- permission is exercised.
-
-
- Implementation Advice
-
- 28 {Long_Integer} An implementation should support Long_Integer in addition
- to Integer if the target machine supports 32-bit (or longer) arithmetic. No
- other named integer subtypes are recommended for package Standard. Instead,
- appropriate named integer subtypes should be provided in the library package
- Interfaces (see B.2).
-
- 28.a Implementation Note: To promote portability, implementations
- should explicitly declare the integer (sub)types Integer and Long_
- Integer in Standard, and leave other predefined integer types
- anonymous. For implementations that already support Byte_Integer,
- etc., upward compatibility argues for keeping such declarations in
- Standard during the transition period, but perhaps generating a
- warning on use. A separate package Interfaces in the predefined
- environment is available for pre-declaring types such as Integer_8,
- Integer_16, etc. See B.2. In any case, if the user declares a
- subtype (first or not) whose range fits in, for example, a byte, the
- implementation can store variables of the subtype in a single byte,
- even if the base range of the type is wider.
-
- 29 {two's complement [modular types]} An implementation for a two's
- complement machine should support modular types with a binary modulus up to
- System.Max_Int*2+2. An implementation should support a nonbinary modulus up
- to Integer'Last.
-
- 29.a Reason: Modular types provide bit-wise "and", "or", "xor",
- and "not" operations. It is important for systems programming that
- these be available for all integer types of the target hardware.
-
- 29.b Ramification: Note that on a one's complement machine, the
- largest supported modular type would normally have a nonbinary
- modulus. On a two's complement machine, the largest supported
- modular type would normally have a binary modulus.
-
- 29.c Implementation Note: Supporting a nonbinary modulus greater
- than Integer'Last can impose an undesirable implementation burden on
- some machines.
-
-
- NOTES
- 30 (25) {universal_integer} {integer literals} Integer literals are of the
- anonymous predefined integer type universal_integer. Other integer
- types have no literals. However, the overload resolution rules (see
- 8.6, ``The Context of Overload Resolution'') allow expressions of the
- type universal_integer whenever an integer type is expected.
-
- 31 (26) The same arithmetic operators are predefined for all signed integer
- types defined by a signed_integer_type_definition (see 4.5, ``Operators
- and Expression Evaluation''). For modular types, these same operators
- are predefined, plus bit-wise logical operators (and, or, xor, and not).
- In addition, for the unsigned types declared in the language-defined
- package Interfaces (see B.2), functions are defined that provide
- bit-wise shifting and rotating.
-
- 32 (27) Modular types match a generic_formal_parameter_declaration of the
- form "type T is mod <>;"; signed integer types match "type T is range
- <>;" (see 12.5.2).
-
-
- Examples
-
- 33 Examples of integer types and subtypes:
-
- 34 type Page_Num is range 1 .. 2_000;
- type Line_Size is range 1 .. Max_Line_Size;
-
- 35 subtype Small_Int is Integer range -10 .. 10;
- subtype Column_Ptr is Line_Size range 1 .. 10;
- subtype Buffer_Size is Integer range 0 .. Max;
-
- 36 type Byte is mod 256; -- an unsigned byte
- type Hash_Index is mod 97; -- modulus is prime
-
-
- Extensions to Ada 83
-
- 36.a {extensions to Ada 83} An implementation is allowed to support
- any number of distinct base ranges for integer types, even if fewer
- integer types are explicitly declared in Standard.
-
- 36.b Modular (unsigned, wrap-around) types are new.
-
- Wording Changes From Ada 83
-
- 36.c Ada 83's integer types are now called "signed" integer types,
- to contrast them with "modular" integer types.
-
- 36.d Standard.Integer, Standard.Long_Integer, etc., denote con-
- strained subtypes of predefined integer types, consistent with the
- Ada 9X model that only subtypes have names.
-
- 36.e We now impose minimum requirements on the base range of
- Integer and Long_Integer.
-
- 36.f We no longer explain integer type definition in terms of an
- equivalence to a normal type derivation, except to say that all
- integer types are by definition implicitly derived from root_integer.
- This is for various reasons.
-
- 36.g First of all, the equivalence with a type derivation and a
- subtype declaration was not perfect, and was the source of various
- AIs (for example, is the conversion of the bounds static? Is a
- numeric type a derived type with respect to other rules of the
- language?)
-
- 36.h Secondly, we don't want to require that every integer size
- supported shall have a corresponding named type in Standard. Adding
- named types to Standard creates nonportabilities.
-
- 36.i Thirdly, we don't want the set of types that match a formal
- derived type "type T is new Integer;" to depend on the particular
- underlying integer representation chosen to implement a given
- user-defined integer type. Hence, we would have needed anonymous
- integer types as parent types for the implicit derivation anyway. We
- have simply chosen to identify only one anonymous integer type --
- root_integer, and stated that every integer type is derived from it.
-
- 36.j Finally, the ``fiction'' that there were distinct preexisting
- predefined types for every supported representation breaks down for
- fixed point with arbitrary smalls, and was never exploited for
- enumeration types, array types, etc. Hence, there seems little
- benefit to pushing an explicit equivalence between integer type
- definition and normal type derivation.
-
-
-
- 3.5.5 Operations of Discrete Types
-
- Static Semantics
-
- 1 For every discrete subtype S, the following attributes are defined:
-
- 2 S'Pos
- S'Pos denotes a function with the following specification:
-
- 3 function S'Pos(Arg : S'Base)
- return universal_integer
-
- 4 This function returns the position number of the value of
- Arg, as a value of type universal_integer.
-
- 5 S'Val
- S'Val denotes a function with the following specification:
-
- 6 function S'Val(Arg : universal_integer)
- return S'Base
-
- 7 {evaluation [Val]} {Constraint_Error (raised by failure
- of run-time check)} This function returns a value of the type
- of S whose position number equals the value of Arg. {Range_
- Check [partial]} {check, language-defined (Range_Check)} For
- the evaluation of a call on S'Val, if there is no value in
- the base range of its type with the given position number,
- Constraint_Error is raised.
-
- 7.a Ramification: By the overload resolution rules, a formal parameter
- of type universal_integer allows an actual parameter of any integer
- type.
-
- 7.b Reason: We considered allowing S'Val for a signed integer subtype S
- to return an out-of-range value, but since checks were required for
- enumeration and modular types anyway, the allowance didn't seem worth
- the complexity of the rule.
-
-
- Implementation Advice
-
- 8 For the evaluation of a call on S'Pos for an enumeration subtype, if the
- value of the operand does not correspond to the internal code for any
- enumeration literal of its type [(perhaps due to an uninitialized variable)],
- then the implementation should raise Program_Error. {Program_Error (raised
- by failure of run-time check)} This is particularly important for enumeration
- types with noncontiguous internal codes specified by an enumeration_
- representation_clause.
-
- 8.a Reason: We say Program_Error here, rather than Constraint_
- Error, because the main reason for such values is uninitialized
- variables, and the normal way to indicate such a use (if detected) is
- to raise Program_Error. (Other reasons would involve the misuse of
- low-level features such as Unchecked_Conversion.)
-
-
- NOTES
- 9 (28) Indexing and loop iteration use values of discrete types.
-
- 10 (29) {predefined operations [of a discrete type]} The predefined
- operations of a discrete type include the assignment operation,
- qualification, the membership tests, and the relational operators; for a
- boolean type they include the short-circuit control forms and the
- logical operators; for an integer type they include type conversion to
- and from other numeric types, as well as the binary and unary adding
- operators - and +, the multiplying operators, the unary operator abs,
- and the exponentiation operator. {94-4693.v} The assignment operation
- is described in 5.2. The other predefined operations are described in
- Section 4.
-
- 11 (30) As for all types, objects of a discrete type have Size and Address
- attributes (see 13.3).
-
- 12 (31) For a subtype of a discrete type, the result delivered by the
- attribute Val might not belong to the subtype; similarly, the actual
- parameter of the attribute Pos need not belong to the subtype. The
- following relations are satisfied (in the absence of an exception) by
- these attributes:
-
- 13 S'Val(S'Pos(X)) = X
- S'Pos(S'Val(N)) = N
-
-
- Examples
-
- 14 Examples of attributes of discrete subtypes:
-
- 15 -- For the types and subtypes declared in subclause 3.5.1 the following ho\
- ld:
-
- 16 -- Color'First = White, Color'Last = Black
- -- Rainbow'First = Red, Rainbow'Last = Blue
-
- 17 -- Color'Succ(Blue) = Rainbow'Succ(Blue) = Brown
- -- Color'Pos(Blue) = Rainbow'Pos(Blue) = 4
- -- Color'Val(0) = Rainbow'Val(0) = White
-
-
- Extensions to Ada 83
-
- 17.a {extensions to Ada 83} The attributes S'Succ, S'Pred, S'Width,
- S'Image, and S'Value have been generalized to apply to real types as
- well (see 3.5, ``Scalar Types'').
-
-
-
- 3.5.6 Real Types
-
- 1 {real type} Real types provide approximations to the real numbers, with
- relative bounds on errors for floating point types, and with absolute bounds
- for fixed point types.
-
-
- Syntax
-
- 2 real_type_definition ::=
- floating_point_definition | fixed_point_definition
-
-
- Static Semantics
-
- 3 {root_real} A type defined by a real_type_definition is implicitly
- derived from root_real, an anonymous predefined (specific) real type.
- [Hence, all real types, whether floating point or fixed point, are in the
- derivation class rooted at root_real.]
-
- 3.a Ramification: It is not specified whether the derivation from
- root_real is direct or indirect, not that it really matters. All we
- want is for all real types to be descendants of root_real.
-
- 4 [{universal_real [partial]} {real literals} Real literals are all of the
- type universal_real, the universal type (see 3.4.1) for the class rooted at
- root_real, allowing their use with the operations of any real type.
- {universal_fixed [partial]} Certain multiplying operators have a result type
- of universal_fixed (see 4.5.5), the universal type for the class of fixed
- point types, allowing the result of the multiplication or division to be used
- where any specific fixed point type is expected.]
-
-
- Dynamic Semantics
-
- 5 {elaboration [real_type_definition]} The elaboration of a real_type_
- definition consists of the elaboration of the floating_point_definition or
- the fixed_point_definition.
-
-
- Implementation Requirements
-
- 6 An implementation shall perform the run-time evaluation of a use of a
- predefined operator of root_real with an accuracy at least as great as that
- of any floating point type definable by a floating_point_definition.
-
- 6.a Ramification: Static calculations using the operators of root_
- real are exact, as for all static calculations. See 4.9.
-
- 6.b Implementation Note: The Digits attribute of the type used to
- represent root_real at run time is at least as great as that of any
- other floating point type defined by a floating_point_definition, and
- its safe range includes that of any such floating point type with the
- same Digits attribute. On some machines, there might be real types
- with less accuracy but a wider range, and hence run-time calculations
- with root_real might not be able to accommodate all values that can
- be represented at run time in such floating point or fixed point
- types.
-
-
- Implementation Permissions
-
- 7 [For the execution of a predefined operation of a real type, the
- implementation need not raise Constraint_Error if the result is outside the
- base range of the type, so long as the correct result is produced, or the
- Machine_Overflows attribute of the type is false (see G.2).]
-
- 8 {nonstandard real type}
-
- 8.a Implementation defined: Any nonstandard real types and the
- operators defined for them.
-
- An implementation may provide nonstandard real types, descendants of root_
- real that are declared outside of the specification of package Standard,
- which need not have all the standard characteristics of a type defined by a
- real_type_definition. For example, a nonstandard real type might have an
- asymmetric or unsigned base range, or its predefined operations might wrap
- around or ``saturate'' rather than overflow (modular or saturating
- arithmetic), or it might not conform to the accuracy model (see G.2). Any
- type descended from a nonstandard real type is also nonstandard. An
- implementation may place arbitrary restrictions on the use of such types; it
- is implementation defined whether operators that are predefined for ``any
- real type'' are defined for a particular nonstandard real type. [In any
- case, such types are not permitted as explicit_generic_actual_parameters for
- formal scalar types -- see 12.5.2.]
-
-
- NOTES
- 9 (32) As stated, real literals are of the anonymous predefined real type
- universal_real. Other real types have no literals. However, the
- overload resolution rules (see 8.6) allow expressions of the type
- universal_real whenever a real type is expected.
-
-
- Wording Changes From Ada 83
-
- 9.a The syntax rule for real_type_definition is modified to use the
- new syntactic categories floating_point_definition and fixed_point_
- definition, instead of floating_point_constraint and fixed_point_
- constraint, because the semantics of a type definition are
- significantly different than the semantics of a constraint.
-
- 9.b All discussion of model numbers, safe ranges, and machine
- numbers is moved to 3.5.7, 3.5.8, and G.2. Values of a fixed point
- type are now described as being multiples of the small of the fixed
- point type, and we have no need for model numbers, safe ranges, etc.
- for fixed point types.
- 3.5.7 Floating Point Types
-
- 1 {floating point type} For floating point types, the error bound is
- specified as a relative precision by giving the required minimum number of
- significant decimal digits.
-
-
- Syntax
-
- 2 floating_point_definition ::=
- digits static_expression [real_range_specification]
-
- 3 real_range_specification ::=
- range static_simple_expression .. static_simple_expression
-
-
- Name Resolution Rules
-
- 4 {requested decimal precision (of a floating point type)} The requested
- decimal precision, which is the minimum number of significant decimal digits
- required for the floating point type, is specified by the value of the
- expression given after the reserved word digits. {expected type [requested
- decimal precision]} This expression is expected to be of any integer type.
-
- 5 {expected type [real_range_specification bounds]} Each simple_expression
- of a real_range_specification is expected to be of any real type[; the types
- need not be the same].
-
-
- Legality Rules
-
- 6 {Max_Base_Digits} The requested decimal precision shall be specified by a
- static expression whose value is positive and no greater than System.Max_
- Base_Digits. Each simple_expression of a real_range_specification shall also
- be static. {Max_Digits} If the real_range_specification is omitted, the
- requested decimal precision shall be no greater than System.Max_Digits.
-
- 6.a Reason: We have added Max_Base_Digits to package System. It
- corresponds to the requested decimal precision of root_real.
- System.Max_Digits corresponds to the maximum value for Digits that
- may be specified in the absence of a real_range_specification, for
- upward compatibility. These might not be the same if root_real has a
- base range that does not include +/- 10.0**(4*Max_Base_Digits).
-
- 7 A floating_point_definition is illegal if the implementation does not
- support a floating point type that satisfies the requested decimal precision
- and range.
-
- 7.a Implementation defined: What combinations of requested decimal
- precision and range are supported for floating point types.
-
-
- Static Semantics
-
- 8 The set of values for a floating point type is the (infinite) set of
- rational numbers. {machine numbers (of a floating point type)} The machine
- numbers of a floating point type are the values of the type that can be
- represented exactly in every unconstrained variable of the type. {base range
- [of a floating point type]} The base range (see 3.5) of a floating point type
- is symmetric around zero, except that it can include some extra negative
- values in some implementations.
-
- 8.a Implementation Note: For example, if a 2's complement
- representation is used for the mantissa rather than a sign-mantissa
- or 1's complement representation, then there is usually one extra
- negative machine number.
-
- 8.b To be honest: If the Signed_Zeros attribute is True, then
- minus zero could in a sense be considered a value of the type.
- However, for most purposes, minus zero behaves the same as plus zero.
- {94-4448.a} {94-4889.e}
-
- 9 {base decimal precision (of a floating point type)} The base decimal
- precision of a floating point type is the number of decimal digits of
- precision representable in objects of the type. {safe range (of a floating
- point type)} The safe range of a floating point type is that part of its base
- range for which the accuracy corresponding to the base decimal precision is
- preserved by all predefined operations.
-
- 9.a Implementation Note: In most cases, the safe range and base
- range are the same. However, for some hardware, values near the
- boundaries of the base range might result in excessive inaccuracies
- or spurious overflows when used with certain predefined operations.
- For such hardware, the safe range would omit such values.
-
- 10 {base decimal precision [of a floating point type]} A floating_point_
- definition defines a floating point type whose base decimal precision is no
- less than the requested decimal precision. {94-4935.a} {94-4913.f} {safe
- range [of a floating point type]} {base range [of a floating point type]} If
- a real_range_specification is given, the safe range of the floating point
- type (and hence, also its base range) includes at least the values of the
- simple expressions given in the real_range_specification. If a real_range_
- specification is not given, the safe (and base) range of the type includes at
- least the values of the range -10.0**(4*D) .. +10.0**(4*D) where D is the
- requested decimal precision. [The safe range might include other values as
- well. The attributes Safe_First and Safe_Last give the actual bounds of the
- safe range.]
-
- 11 A floating_point_definition also defines a first subtype of the type.
- {constrained (subtype)} {unconstrained (subtype)} If a real_range_
- specification is given, then the subtype is constrained to a range whose
- bounds are given by a conversion of the values of the simple_expressions of
- the real_range_specification to the type being defined. {implicit subtype
- conversion [bounds of a floating point type]} Otherwise, the subtype is
- unconstrained.
-
- 12 {Float} There is a predefined, unconstrained, floating point subtype
- named Float[, declared in the visible part of package Standard].
-
-
- Dynamic Semantics
-
- 13 {elaboration [floating_point_definition]} [The elaboration of a
- floating_point_definition creates the floating point type and its first
- subtype.]
-
-
- Implementation Requirements
-
- 14 {Float} In an implementation that supports floating point types with 6
- or more digits of precision, the requested decimal precision for Float shall
- be at least 6.
-
- 15 {Long_Float} If Long_Float is predefined for an implementation, then its
- requested decimal precision shall be at least 11.
-
-
- Implementation Permissions
-
- 16 {Short_Float} {Long_Float} An implementation is allowed to provide
- additional predefined floating point types[, declared in the visible part of
- Standard], whose (unconstrained) first subtypes have names of the form Short_
- Float, Long_Float, Short_Short_Float, Long_Long_Float, etc. Different
- predefined floating point types are allowed to have the same base decimal
- precision. However, the precision of Float should be no greater than that of
- Long_Float. Similarly, the precision of Short_Float (if provided) should be
- no greater than Float. Corresponding recommendations apply to any other
- predefined floating point types. There need not be a named floating point
- type corresponding to each distinct base decimal precision supported by an
- implementation.
-
- 16.a Implementation defined: The predefined floating point types
- declared in Standard.
-
-
- Implementation Advice
-
- 17 {Long_Float} An implementation should support Long_Float in addition to
- Float if the target machine supports 11 or more digits of precision. No
- other named floating point subtypes are recommended for package Standard.
- Instead, appropriate named floating point subtypes should be provided in the
- library package Interfaces (see B.2).
-
- 17.a Implementation Note: To promote portability, implementations
- should explicitly declare the floating point (sub)types Float and
- Long_Float in Standard, and leave other predefined float types
- anonymous. For implementations that already support Short_Float,
- etc., upward compatibility argues for keeping such declarations in
- Standard during the transition period, but perhaps generating a
- warning on use. A separate package Interfaces in the predefined
- environment is available for pre-declaring types such as Float_32,
- IEEE_Float_64, etc. See B.2.
-
-
- NOTES
- 18 (33) If a floating point subtype is unconstrained, then assignments to
- variables of the subtype involve only Overflow_Checks, never Range_
- Checks.
-
-
- Examples
-
- 19 Examples of floating point types and subtypes:
-
- 20 type Coefficient is digits 10 range -1.0 .. 1.0;
-
- 21 type Real is digits 8;
- type Mass is digits 7 range 0.0 .. 1.0E35;
-
- 22 subtype Probability is Real range 0.0 .. 1.0; -- a subtype with a small\
- er range
-
-
- Inconsistencies With Ada 83
-
- 22.a {inconsistencies with Ada 83} No Range_Checks, only Overflow_
- Checks, are performed on variables (or parameters) of an
- unconstrained floating point subtype. This is upward compatible for
- programs that do not raise Constraint_Error. For those that do raise
- Constraint_Error, it is possible that the exception will be raised at
- a later point, or not at all, if extended range floating point
- registers are used to hold the value of the variable (or parameter).
-
- 22.b Reason: This change was felt to be justified by the
- possibility of improved performance on machines with extended-range
- floating point registers. An implementation need not take advantage
- of this relaxation in the range checking; it can hide completely the
- use of extended range registers if desired, presumably at some
- run-time expense.
- Wording Changes From Ada 83
-
- 22.c The syntax rules for floating_point_constraint and floating_
- accuracy_definition are removed. The syntax rules for floating_
- point_definition and real_range_specification are new.
-
- 22.d A syntax rule for digits_constraint is given in 3.5.9, ``Fixed
- Point Types''. In J.3 we indicate that a digits_constraint may be
- applied to a floating point subtype_mark as well (to be compatible
- with Ada 83's floating_point_constraint).
-
- 22.e Discussion of model numbers is postponed to 3.5.8 and G.2.
- The concept of safe numbers has been replaced by the concept of the
- safe range of values. The bounds of the safe range are given by
- T'Safe_First .. T'Safe_Last, rather than -T'Safe_Large .. T'Safe_
- Large, since on some machines the safe range is not perfectly
- symmetric. The concept of machine numbers is new, and is relevant to
- the definition of Succ and Pred for floating point numbers.
-
-
-
- 3.5.8 Operations of Floating Point Types
-
- Static Semantics
-
- 1 The following attribute is defined for every floating point subtype S:
-
- 1.a Change: Editorial change -- plural to singular in above
- phrase.
-
- 2 S'Digits
- S'Digits denotes the requested decimal precision for the
- subtype S. The value of this attribute is of the type
- universal_integer. The requested decimal precision of the
- base subtype of a floating point type T is defined to be the
- largest value of d for which ceiling(d * log(10) /
- log(T'Machine_Radix)) + 1 <= T'Model_Mantissa. {94-4935.a}
- {94-4913.f}
-
-
- NOTES
- 3 (34) {predefined operations [of a floating point type]} The predefined
- operations of a floating point type include the assignment operation,
- qualification, the membership tests, and explicit conversion to and from
- other numeric types. They also include the relational operators and the
- following predefined arithmetic operators: the binary and unary adding
- operators - and +, certain multiplying operators, the unary operator
- abs, and the exponentiation operator. {94-4693.v}
-
- 4 (35) As for all types, objects of a floating point type have Size and
- Address attributes (see 13.3). Other attributes of floating point types
- are defined in A.5.3.
-
-
-
- 3.5.9 Fixed Point Types
-
- 1 {fixed point type} {ordinary fixed point type} {decimal fixed point type}
- A fixed point type is either an ordinary fixed point type, or a decimal fixed
- point type. {delta (of a fixed point type)} The error bound of a fixed point
- type is specified as an absolute value, called the delta of the fixed point
- type.
-
-
- Syntax
-
- 2 fixed_point_definition ::= ordinary_fixed_point_definition | decimal_fixed_\
- point_definition
-
- 3 ordinary_fixed_point_definition ::=
- delta static_expression real_range_specification
-
- 4 decimal_fixed_point_definition ::=
- delta static_expression digits static_expression [real_range_specificati\
- on]
-
- 5 digits_constraint ::=
- digits static_expression [range_constraint]
-
-
- Name Resolution Rules
-
- 6 {expected type [fixed point type delta]} For a type defined by a fixed_
- point_definition, the delta of the type is specified by the value of the
- expression given after the reserved word delta; this expression is expected
- to be of any real type. {expected type [decimal fixed point type digits]}
- {digits (of a decimal fixed point subtype)} {decimal fixed point type} For a
- type defined by a decimal_fixed_point_definition (a decimal fixed point
- type), the number of significant decimal digits for its first subtype (the
- digits of the first subtype) is specified by the expression given after the
- reserved word digits; this expression is expected to be of any integer type.
-
-
- Legality Rules
-
- 7 In a fixed_point_definition or digits_constraint, the expressions given
- after the reserved words delta and digits shall be static; their values shall
- be positive.
-
- 8 {small (of a fixed point type)} The set of values of a fixed point type
- comprise the integral multiples of a number called the small of the type.
- {ordinary fixed point type} For a type defined by an ordinary_fixed_point_
- definition (an ordinary fixed point type), the small may be specified by an
- attribute_definition_clause (see 13.3); if so specified, it shall be no
- greater than the delta of the type. If not specified, the small of an
- ordinary fixed point type is an implementation-defined power of two less than
- or equal to the delta.
-
- 8.a Implementation defined: The small of an ordinary fixed point
- type.
-
- 9 For a decimal fixed point type, the small equals the delta; the delta
- shall be a power of 10. If a real_range_specification is given, both bounds
- of the range shall be in the range -(10**digits-1)*delta ..
- +(10**digits-1)*delta.
-
- 10 A fixed_point_definition is illegal if the implementation does not
- support a fixed point type with the given small and specified range or
- digits.
-
- 10.a Implementation defined: What combinations of small, range,
- and digits are supported for fixed point types.
-
- 11 For a subtype_indication with a digits_constraint, the subtype_mark
- shall denote a decimal fixed point subtype.
-
- 11.a To be honest: Or, as an obsolescent feature, a floating point
- subtype is permitted -- see J.3.
-
-
- Static Semantics
-
- 12 {base range [of a fixed point type]} The base range (see 3.5) of a fixed
- point type is symmetric around zero, except possibly for an extra negative
- value in some implementations.
-
- 13 {base range [of an ordinary fixed point type]} An ordinary_fixed_point_
- definition defines an ordinary fixed point type whose base range includes at
- least all multiples of small that are between the bounds specified in the
- real_range_specification. The base range of the type does not necessarily
- include the specified bounds themselves. {constrained (subtype)}
- {unconstrained (subtype)} An ordinary_fixed_point_definition also defines a
- constrained first subtype of the type, with each bound of its range given by
- the closer to zero of:
-
- 14 the value of the conversion to the fixed point type of the
- corresponding expression of the real_range_specification;
- {implicit subtype conversion [bounds of a fixed point type]}
-
- 15 the corresponding bound of the base range.
-
- 16 {base range [of a decimal fixed point type]} A decimal_fixed_point_
- definition defines a decimal fixed point type whose base range includes at
- least the range -(10**digits-1)*delta .. +(10**digits-1)*delta. {constrained
- (subtype)} {unconstrained (subtype)} A decimal_fixed_point_definition also
- defines a constrained first subtype of the type. If a real_range_
- specification is given, the bounds of the first subtype are given by a
- conversion of the values of the expressions of the real_range_specification.
- {implicit subtype conversion [bounds of a decimal fixed point type]}
- Otherwise, the range of the first subtype is -(10**digits-1)*delta ..
- +(10**digits-1)*delta.
-
-
- Dynamic Semantics
-
- 17 {elaboration [fixed_point_definition]} The elaboration of a fixed_point_
- definition creates the fixed point type and its first subtype.
-
- 18 For a digits_constraint on a decimal fixed point subtype with a given
- delta, if it does not have a range_constraint, then it specifies an implicit
- range -(10**D-1)*delta .. +(10**D-1)*delta, where D is the value of the
- expression. {compatibility (digits_constraint with a decimal fixed point
- subtype)} A digits_constraint is compatible with a decimal fixed point
- subtype if the value of the expression is no greater than the digits of the
- subtype, and if it specifies (explicitly or implicitly) a range that is
- compatible with the subtype.
-
- 18.a Discussion: Except for the requirement that the digits
- specified be no greater than the digits of the subtype being
- constrained, a digits_constraint is essentially equivalent to a
- range_constraint.
-
- 18.b Consider the following example:
-
- 18.c type D is delta 0.01 digits 7 range -0.00 .. 9999.99;
-
- 18.d The compatibility rule implies that the digits_constraint
- "digits 6" specifies an implicit range of "- 99.9999 .. 99.9999".
- Thus, "digits 6" is not compatible with the constraint of D, but
- "digits 6 range 0.00 .. 9999.99" is compatible. {94-4502.a}
-
- 18.e A value of a scalar type belongs to a constrained subtype of
- the type if it belongs to the range of the subtype. Attributes like
- Digits and Delta have no affect on this fundamental rule. So the
- obsolescent forms of digits_constraints and delta_constraints that
- are called ``accuracy constraints'' in RM83 don't really represent
- constraints on the values of the subtype, but rather primarily affect
- compatibility of the ``constraint'' with the subtype being
- ``constrained.'' In this sense, they might better be called
- ``subtype assertions'' rather than ``constraints.''
-
- 18.f Note that the digits_constraint on a decimal fixed point
- subtype is a combination of an assertion about the digits of the
- subtype being further constrained, and a constraint on the range of
- the subtype being defined, either explicit or implicit.
-
- 19 {elaboration [digits_constraint]} The elaboration of a digits_constraint
- consists of the elaboration of the range_constraint, if any. {Range_Check
- [partial]} {check, language-defined (Range_Check)} If a range_constraint is
- given, a check is made that the bounds of the range are both in the range
- -(10**D-1)*delta .. +(10**D-1)*delta, where D is the value of the (static)
- expression given after the reserved word digits. {Constraint_Error (raised
- by failure of run-time check)} If this check fails, Constraint_Error is
- raised.
-
-
- Implementation Requirements
-
- 20 The implementation shall support at least 24 bits of precision
- (including the sign bit) for fixed point types.
-
- 20.a Reason: This is sufficient to represent Standard.Duration
- with a small no more than 50 milliseconds.
-
-
- Implementation Permissions
-
- 21 Implementations are permitted to support only smalls that are a power of
- two. In particular, all decimal fixed point type declarations can be
- disallowed. Note however that conformance with the Information Systems Annex
- requires support for decimal smalls, and decimal fixed point type
- declarations with digits up to at least 18.
-
- 21.a Implementation Note: The accuracy requirements for
- multiplication, division, and conversion (see G.2.1, ``Model of
- Floating Point Arithmetic'') are such that support for arbitrary
- smalls should be practical without undue implementation effort.
- Therefore, implementations should support fixed point types with
- arbitrary values for small (within reason). One reasonable
- limitation would be to limit support to fixed point types that can be
- converted to the most precise floating point type without loss of
- precision (so that Fixed_IO is implementable in terms of Float_IO).
-
-
- NOTES
- 22 (36) The base range of an ordinary fixed point type need not include
- the specified bounds themselves so that the range specification can be
- given in a natural way, such as:
-
- 23 type Fraction is delta 2.0**(-15) range -1.0 .. 1.0;
-
- 24 With 2's complement hardware, such a type could have a signed
- 16-bit representation, using 1 bit for the sign and 15 bits for
- fraction, resulting in a base range of -1.0 .. 1.0-2.0**(-15).
-
-
- Examples
-
- 25 Examples of fixed point types and subtypes:
-
- 26 type Volt is delta 0.125 range 0.0 .. 255.0;
-
- 27 -- A pure fraction which requires all the available
- -- space in a word can be declared as the type Fraction:
- type Fraction is delta System.Fine_Delta range -1.0 .. 1.0;
- -- Fraction'Last = 1.0 - System.Fine_Delta
-
- 28 type Money is delta 0.01 digits 15; -- decimal fixed point
- subtype Salary is Money digits 10;
- -- Money'Last = 10.0**13 - 0.01, Salary'Last = 10.0**8 - 0.01
-
-
- Inconsistencies With Ada 83
-
- 28.a {inconsistencies with Ada 83} In Ada 9X, S'Small always equals
- S'Base'Small, so if an implementation chooses a small for a fixed
- point type smaller than required by the delta, the value of S'Small
- in Ada 9X might not be the same as it was in Ada 83.
-
- Extensions to Ada 83
-
- 28.b {extensions to Ada 83} Decimal fixed point types are new,
- though their capabilities are essentially similar to that available
- in Ada 83 with a fixed point type whose small equals its delta equals
- a power of 10. However, in the Information Systems Annex, additional
- requirements are placed on the support of decimal fixed point types
- (e.g. a minimum of 18 digits of precision).
-
- Wording Changes From Ada 83
-
- 28.c The syntax rules for fixed_point_constraint and fixed_
- accuracy_definition are removed. The syntax rule for fixed_point_
- definition is new. A syntax rule for delta_constraint is included in
- the Obsolescent features (to be compatible with Ada 83's fixed_point_
- constraint).
-
-
-
- 3.5.10 Operations of Fixed Point Types
-
- Static Semantics
-
- 1 The following attributes are defined for every fixed point subtype S:
-
- 2 S'Small
- S'Small denotes the small of the type of S. The value of this
- attribute is of the type universal_real. {specifiable [of
- Small for fixed point types]} {Small clause} Small may be
- specified for nonderived fixed point types via an attribute_
- definition_clause (see 13.3); the expression of such a clause
- shall be static.
-
- 3 S'Delta
- S'Delta denotes the delta of the fixed point subtype S. The
- value of this attribute is of the type universal_real.
-
- 3.a Reason: The delta is associated with the subtype as opposed to the
- type, because of the possibility of an (obsolescent) delta_
- constraint.
-
- 4 S'Fore
- S'Fore yields the minimum number of characters needed before
- the decimal point for the decimal representation of any value
- of the subtype S, assuming that the representation does not
- include an exponent, but includes a one-character prefix that
- is either a minus sign or a space. (This minimum number does
- not include superfluous zeros or underlines, and is at least
- 2.) The value of this attribute is of the type universal_
- integer.
-
- 5 S'Aft
- S'Aft yields the number of decimal digits needed after the
- decimal point to accommodate the delta of the subtype S,
- unless the delta of the subtype S is greater than 0.1, in
- which case the attribute yields the value one. [(S'Aft is
- the smallest positive integer N for which (10**N)*S'Delta is
- greater than or equal to one.)] The value of this attribute
- is of the type universal_integer.
-
- 6 The following additional attributes are defined for every decimal fixed
- point subtype S:
-
- 7 S'Digits
- S'Digits denotes the digits of the decimal fixed point
- subtype S, which corresponds to the number of decimal digits
- that are representable in objects of the subtype. The value
- of this attribute is of the type universal_integer. Its
- value is determined as follows: {94-4768.k} {digits (of a
- decimal fixed point subtype)}
-
- 8 For a first subtype or a subtype defined by a
- subtype_indication with a digits_constraint, the
- digits is the value of the expression given after
- the reserved word digits;
-
- 9 For a subtype defined by a subtype_indication
- without a digits_constraint, the digits of the
- subtype is the same as that of the subtype
- denoted by the subtype_mark in the subtype_
- indication.
-
- 9.a Implementation Note: Although a decimal subtype can be both
- range-constrained and digits-constrained, the digits constraint
- is intended to control the Size attribute of the subtype. For
- decimal types, Size can be important because input/output of
- decimal types is so common.
-
- 10 The digits of a base subtype is the largest
- integer D such that the range -(10**D-1)*delta ..
- +(10**D-1)*delta is included in the base range of
- the type.
-
- 10.a Change: Made 3.5.10(10);5.7 into a bullet under S'Digits, rather
- than separately listing it under S'Base'Digits, as per WG9
- resolution.
-
- 11 S'Scale
- S'Scale denotes the scale of the subtype S, defined as the
- value N such that S'Delta = 10.0**(-N). {scale (of a decimal
- fixed point subtype)} [The scale indicates the position of
- the point relative to the rightmost significant digits of
- values of subtype S.] The value of this attribute is of the
- type universal_integer.
-
- 11.a Ramification: S'Scale is negative if S'Delta is greater than one.
- By contrast, S'Aft is always positive.
-
- 12 S'Round
- S'Round denotes a function with the following specification:
-
- 13 function S'Round(X : universal_real)
- return S'Base
-
- 14 The function returns the value obtained by rounding X
- (away from 0, if X is midway between two values of the type
- of S).
- NOTES
- 15 (37) All subtypes of a fixed point type will have the same value for the
- Delta attribute, in the absence of delta_constraints (see J.3).
-
- 16 (38) S'Scale is not always the same as S'Aft for a decimal subtype; for
- example, if S'Delta = 1.0 then S'Aft is 1 while S'Scale is 0.
-
- 17 (39) {predefined operations [of a fixed point type]} The predefined
- operations of a fixed point type include the assignment operation,
- qualification, the membership tests, and explicit conversion to and from
- other numeric types. They also include the relational operators and the
- following predefined arithmetic operators: the binary and unary adding
- operators - and +, multiplying operators, and the unary operator abs.
-
- 18 (40) As for all types, objects of a fixed point type have Size and
- Address attributes (see 13.3). Other attributes of fixed point types
- are defined in A.5.4.
-
-
-
- 3.6 Array Types
-
- 1 {array} {array type} An array object is a composite object consisting of
- components which all have the same subtype. The name for a component of an
- array uses one or more index values belonging to specified discrete types.
- The value of an array object is a composite value consisting of the values of
- the components.
-
-
- Syntax
-
- 2 array_type_definition ::=
- unconstrained_array_definition | constrained_array_definition
-
- 3 unconstrained_array_definition ::=
- array(index_subtype_definition {, index_subtype_definition}) of componen\
- t_definition
-
- 4 index_subtype_definition ::= subtype_mark range <>
-
- 5 constrained_array_definition ::=
- array (discrete_subtype_definition {, discrete_subtype_definition}) of c\
- omponent_definition
-
- 6 discrete_subtype_definition ::= discrete_subtype_indication | range
-
- 7 component_definition ::= [aliased] subtype_indication
-
-
- Name Resolution Rules
-
- 8 {expected type [discrete_subtype_definition range]} For a discrete_
- subtype_definition that is a range, the range shall resolve to be of some
- specific discrete type[; which discrete type shall be determined without
- using any context other than the bounds of the range itself (plus the
- preference for root_integer -- see 8.6).]
-
-
- Legality Rules
-
- 9 {index subtype} Each index_subtype_definition or discrete_subtype_
- definition in an array_type_definition defines an index subtype; {index type}
- its type (the index type) shall be discrete.
-
- 9.a Discussion: {index (of an array)} An index is a discrete
- quantity used to select along a given dimension of an array. A
- component is selected by specifying corresponding values for each of
- the indices.
-
- 10 {component subtype} The subtype defined by the subtype_indication of a
- component_definition (the component subtype) shall be a definite subtype.
-
- 10.a Ramification: This applies to all uses of component_
- definition, including in record_type_definitions and protected_
- definitions.
-
- 11 Within the definition of a nonlimited composite type (or a limited
- composite type that later in its immediate scope becomes nonlimited -- see
- 7.3.1 and 7.5), if a component_definition contains the reserved word aliased
- and the type of the component is discriminated, then the nominal subtype of
- the component shall be constrained.
-
- 11.a Reason: If we allowed the subtype to be unconstrained, then
- the discriminants might change because of an assignment to the
- containing (nonlimited) object, thus causing a potential violation of
- an access subtype constraint of an access value designating the
- aliased component.
-
- 11.b Note that the rule elsewhere defining all aliased
- discriminated objects to be constrained does not help -- that rule
- prevents assignments to the component itself from doing any harm, but
- not assignments to the containing object. {94-4858.a}
-
- 11.c We allow this for components within limited types since
- assignment to the enclosing object is not a problem. Furthermore, it
- is important to be able to use a default expression for a
- discriminant in arrays of limited components, since that is the only
- way to give the components different values for their discriminants.
- For example:
-
- 11.d protected type Counter_Type(Initial_Value : Integer := 1) is
- procedure Get_Next(Next_Value : out Integer);
- -- Returns the next value on each call, bumping Count
- -- before returning.
- private
- Count : Integer := Initial_Value;
- end Counter_Type;
- protected body Counter_Type is ...
-
- 11.e function Next_Id(Counter : access Counter_Type) return Integer is
- Result : Integer;
- begin
- Counter.Get_Next(Result);
- return Result;
- end Next_Id;
-
- 11.f C : aliased Counter_Type;
- task type T(Who_Am_I : Integer := Next_Id(C'Access));
- task body T is ...
-
- 11.g Task_Array : array(1..100) of aliased T;
- -- Array of task elements, each with its own unique ID.
- -- We specify "aliased" so we can use Task_Array(I)'Access.
- -- This is safe because Task_Array is of a limited type,
- -- so there is no way an assignment to it could change
- -- the discriminants of one of its components.
-
- 11.h Ramification: Note that this rule applies to array components
- and record components, but not to protected type components (since
- they are always limited).
-
-
- Static Semantics
-
- 12 {dimensionality (of an array)} {one-dimensional array} {multi-
- dimensional array} An array is characterized by the number of indices (the
- dimensionality of the array), the type and position of each index, the lower
- and upper bounds for each index, and the subtype of the components. The
- order of the indices is significant.
-
- 13 A one-dimensional array has a distinct component for each possible index
- value. A multidimensional array has a distinct component for each possible
- sequence of index values that can be formed by selecting one value for each
- index position (in the given order). The possible values for a given index
- are all the values between the lower and upper bounds, inclusive; {index
- range} this range of values is called the index range. {bounds (of an
- array)} The bounds of an array are the bounds of its index ranges. {length
- (of a dimension of an array)} The length of a dimension of an array is the
- number of values of the index range of the dimension (zero for a null range).
- {length (of a one-dimensional array)} The length of a one-dimensional array
- is the length of its only dimension.
-
- 14 An array_type_definition defines an array type and its first subtype.
- For each object of this array type, the number of indices, the type and
- position of each index, and the subtype of the components are as in the type
- definition[; the values of the lower and upper bounds for each index belong
- to the corresponding index subtype of its type, except for null arrays (see
- 3.6.1)].
-
- 15 {constrained (subtype)} {unconstrained (subtype)} An unconstrained_
- array_definition defines an array type with an unconstrained first subtype.
- Each index_subtype_definition defines the corresponding index subtype to be
- the subtype denoted by the subtype_mark.[{box [compound delimiter]} The
- compound delimiter <> (called a box) of an index_subtype_definition stands
- for an undefined range (different objects of the type need not have the same
- bounds).]
-
- 16 {constrained (subtype)} {unconstrained (subtype)} A constrained_array_
- definition defines an array type with a constrained first subtype. Each
- discrete_subtype_definition defines the corresponding index subtype, as well
- as the corresponding index range for the constrained first subtype.
- {constraint [of a first array subtype]} The constraint of the first subtype
- consists of the bounds of the index ranges.
-
- 16.a Discussion: Although there is no namable unconstrained array
- subtype in this case, the predefined slicing and concatenation
- operations can operate on and yield values that do not necessarily
- belong to the first array subtype. This is also true for Ada 83.
-
- 17 The discrete subtype defined by a discrete_subtype_definition is either
- that defined by the subtype_indication, or a subtype determined by the range
- as follows:
-
- 18 If the type of the range resolves to root_integer, then the
- discrete_subtype_definition defines a subtype of the predefined
- type Integer with bounds given by a conversion to Integer of the
- bounds of the range; {implicit subtype conversion [bounds of a
- range]}
-
- 18.a Reason: This ensures that indexing over the discrete subtype
- can be performed with regular Integers, rather than only
- universal_integers.
-
- 18.b Discussion: We considered doing this by simply creating a
- ``preference'' for Integer when resolving the range.
- {Beaujolais effect [partial]} However, this can introduce
- Beaujolais effects when the simple_expressions involve calls on
- functions visible due to use clauses.
-
- 19 Otherwise, the discrete_subtype_definition defines a subtype of
- the type of the range, with the bounds given by the range.
-
- 20 {nominal subtype [of a component]} The component_definition of an array_
- type_definition defines the nominal subtype of the components. If the
- reserved word aliased appears in the component_definition, then each
- component of the array is aliased (see 3.10).
-
- 20.a Ramification: In this case, the nominal subtype cannot be an
- unconstrained discriminated subtype. See 3.8.
-
-
- Dynamic Semantics
-
- 21 {elaboration [array_type_definition]} The elaboration of an array_type_
- definition creates the array type and its first subtype, and consists of the
- elaboration of any discrete_subtype_definitions and the component_definition.
-
- 22 {elaboration [discrete_subtype_definition]} The elaboration of a
- discrete_subtype_definition creates the discrete subtype, and consists of the
- elaboration of the subtype_indication or the evaluation of the range.
- {elaboration [component_definition]} The elaboration of a component_
- definition in an array_type_definition consists of the elaboration of the
- subtype_indication. The elaboration of any discrete_subtype_definitions and
- the elaboration of the component_definition are performed in an arbitrary
- order.
-
-
- NOTES
- 23 (41) All components of an array have the same subtype. In particular,
- for an array of components that are one-dimensional arrays, this means
- that all components have the same bounds and hence the same length.
-
- 24 (42) Each elaboration of an array_type_definition creates a distinct
- array type. A consequence of this is that each object whose object_
- declaration contains an array_type_definition is of its own unique type.
-
-
- Examples
-
- 25 Examples of type declarations with unconstrained array definitions:
-
- 26 type Vector is array(Integer range <>) of Real;
- type Matrix is array(Integer range <>, Integer range <>) of Real;
- type Bit_Vector is array(Integer range <>) of Boolean;
- type Roman is array(Positive range <>) of Roman_Digit; -- see 3.5.2
-
- 27 Examples of type declarations with constrained array definitions:
-
- 28 type Table is array(1 .. 10) of Integer;
- type Schedule is array(Day) of Boolean;
- type Line is array(1 .. Max_Line_Size) of Character;
-
- 29 Examples of object declarations with array type definitions:
-
- 30 Grid : array(1 .. 80, 1 .. 100) of Boolean;
- Mix : array(Color range Red .. Green) of Boolean;
- Page : array(Positive range <>) of Line := -- an array of arrays
- (1 | 50 => Line'(1 | Line'Last => '+', others => '-'), -- see 4.3.3
- 2 .. 49 => Line'(1 | Line'Last => '|', others => ' '));
- -- Page is constrained by its initial value to (1..50)
-
-
- Extensions to Ada 83
-
- 30.a {extensions to Ada 83} The syntax rule for component_
- definition is modified to allow the reserved word aliased.
-
- 30.b The syntax rules for unconstrained_array_definition and
- constrained_array_definition are modified to use component_definition
- (instead of component_subtype_indication). The effect of this change
- is to allow the reserved word aliased before the component subtype_
- indication.
-
- 30.c A range in a discrete_subtype_definition may use arbitrary
- universal expressions for each bound (e.g. -1 .. 3+5), rather than
- strictly "implicitly convertible" operands. The subtype defined will
- still be a subtype of Integer.
-
- Wording Changes From Ada 83
-
- 30.d We introduce a new syntactic category, discrete_subtype_
- definition, as distinct from discrete_range. These two constructs
- have the same syntax, but their semantics are quite different (one
- defines a subtype, with a preference for Integer subtypes, while the
- other just selects a subrange of an existing subtype). We use this
- new syntactic category in for loops and entry families.
-
- 30.e The syntax for index_constraint and discrete_range have been
- moved to their own subclause, since they are no longer used here.
-
- 30.f The syntax rule for component_definition (formerly component_
- subtype_definition) is moved here from RM83-3.7.
-
-
-
- 3.6.1 Index Constraints and Discrete Ranges
-
- 1 An index_constraint determines the range of possible values for every
- index of an array subtype, and thereby the corresponding array bounds.
-
-
- Syntax
-
- 2 index_constraint ::= (discrete_range {, discrete_range})
-
- 3 discrete_range ::= discrete_subtype_indication | range
-
-
- Name Resolution Rules
-
- 4 {type of a discrete_range} The type of a discrete_range is the type of
- the subtype defined by the subtype_indication, or the type of the range.
- {expected type [index_constraint discrete_range]} For an index_constraint,
- each discrete_range shall resolve to be of the type of the corresponding
- index.
-
- 4.a Discussion: In Ada 9X, index_constraints only appear in a
- subtype_indication; they no longer appear in constrained_array_
- definitions.
-
-
- Legality Rules
-
- 5 An index_constraint shall appear only in a subtype_indication whose
- subtype_mark denotes either an unconstrained array subtype, or an
- unconstrained access subtype whose designated subtype is an unconstrained
- array subtype; in either case, the index_constraint shall provide a discrete_
- range for each index of the array type.
-
-
- Static Semantics
-
- 6 {bounds (of a discrete_range)} A discrete_range defines a range whose
- bounds are given by the range, or by the range of the subtype defined by the
- subtype_indication.
-
-
- Dynamic Semantics
-
- 7 {compatibility [index constraint with a subtype]} An index_constraint is
- compatible with an unconstrained array subtype if and only if the index range
- defined by each discrete_range is compatible (see 3.5) with the corresponding
- index subtype. {null array} If any of the discrete_ranges defines a null
- range, any array thus constrained is a null array, having no components.
- {satisfies [an index constraint]} An array value satisfies an index_
- constraint if at each index position the array value and the index_constraint
- have the same index bounds.
-
- 7.a Ramification: There is no need to define compatibility with a
- constrained array subtype, because one is not allowed to constrain it
- again.
-
- 8 {elaboration [index_constraint]} The elaboration of an index_constraint
- consists of the evaluation of the discrete_range(s), in an arbitrary order.
- {evaluation [discrete_range]} The evaluation of a discrete_range consists of
- the elaboration of the subtype_indication or the evaluation of the range.
-
-
- NOTES
- 9 (43) The elaboration of a subtype_indication consisting of a subtype_
- mark followed by an index_constraint checks the compatibility of the
- index_constraint with the subtype_mark (see 3.2.2).
-
- 10 (44) Even if an array value does not satisfy the index constraint of an
- array subtype, Constraint_Error is not raised on conversion to the array
- subtype, so long as the length of each dimension of the array value and
- the array subtype match. See 4.6.
-
-
- Examples
-
- 11 Examples of array declarations including an index constraint:
-
- 12 Board : Matrix(1 .. 8, 1 .. 8); -- see 3.6
- Rectangle : Matrix(1 .. 20, 1 .. 30);
- Inverse : Matrix(1 .. N, 1 .. N); -- N need not be static
-
- 13 Filter : Bit_Vector(0 .. 31);
-
- 14 Example of array declaration with a constrained array subtype:
-
- 15 My_Schedule : Schedule; -- all arrays of type Schedule have the same boun\
- ds
-
- 16 Example of record type with a component that is an array:
-
- 17 type Var_Line(Length : Natural) is
- record
- Image : String(1 .. Length);
- end record;
-
- 18 Null_Line : Var_Line(0); -- Null_Line.Image is a null array
-
-
- Extensions to Ada 83
-
- 18.a {extensions to Ada 83} We allow the declaration of a variable
- with a nominally unconstrained array subtype, so long as it has an
- initialization expression to determine its bounds.
- Wording Changes From Ada 83
-
- 18.b We have moved the syntax for index_constraint and discrete_
- range here since they are no longer used in constrained_array_
- definitions. We therefore also no longer have to describe the
- (special) semantics of index_constraints and discrete_ranges that
- appear in constrained_array_definitions.
-
- 18.c The rules given in RM83-3.6.1(5,7-10), which define the bounds
- of an array object, are redundant with rules given elsewhere, and so
- are not repeated here. RM83-3.6.1(6), which requires that the
- (nominal) subtype of an array variable be constrained, no longer
- applies, so long as the variable is explicitly initialized.
-
-
-
- 3.6.2 Operations of Array Types
-
- Legality Rules
-
- 1 [The argument N used in the attribute_designators for the N-th dimension
- of an array shall be a static expression of some integer type.] The value of
- N shall be positive (nonzero) and no greater than the dimensionality of the
- array.
-
-
- Static Semantics
-
- 2 The following attributes are defined for a prefix A that is of an array
- type [(after any implicit dereference)], or denotes a constrained array
- subtype:
-
- 2.a Ramification: These attributes are not defined if A is a
- subtype-mark for an access-to-array subtype. They are defined (by
- implicit dereference) for access-to-array values.
-
- 3 A'First
- A'First denotes the lower bound of the first index range; its
- type is the corresponding index type.
-
- 4 A'First(N)
- A'First(N) denotes the lower bound of the N-th index range;
- its type is the corresponding index type.
-
- 5 A'Last
- A'Last denotes the upper bound of the first index range; its
- type is the corresponding index type.
-
- 6 A'Last(N)
- A'Last(N) denotes the upper bound of the N-th index range;
- its type is the corresponding index type.
-
- 7 A'Range
- A'Range is equivalent to the range A'First .. A'Last, except
- that the prefix A is only evaluated once.
-
- 8 A'Range(N)
- A'Range(N) is equivalent to the range A'First(N) ..
- A'Last(N), except that the prefix A is only evaluated once.
-
- 9 A'Length
- A'Length denotes the number of values of the first index
- range (zero for a null range); its type is universal_integer.
-
- 10 A'Length(N)
- A'Length(N) denotes the number of values of the N-th index
- range (zero for a null range); its type is universal_integer.
-
-
- Implementation Advice
-
- 11 An implementation should normally represent multidimensional arrays in
- row-major order, consistent with the notation used for multidimensional array
- aggregates (see 4.3.3). However, if a pragma Convention(Fortran, ...)
- applies to a multidimensional array type, then column-major order should be
- used instead (see B.5, ``Interfacing with Fortran'').
-
-
- NOTES
- 12 (45) The attribute_references A'First and A'First(1) denote the same
- value. A similar relation exists for the attribute_references A'Last,
- A'Range, and A'Length. The following relation is satisfied (except for
- a null array) by the above attributes if the index type is an integer
- type:
-
- 13 A'Length(N) = A'Last(N) - A'First(N) + 1
-
- 14 (46) An array type is limited if its component type is limited (see
- 7.5).
-
- 15 (47) {predefined operations [of an array type]} The predefined
- operations of an array type include the membership tests, qualification,
- and explicit conversion. If the array type is not limited, they also
- include assignment and the predefined equality operators. For a
- one-dimensional array type, they include the predefined concatenation
- operators (if nonlimited) and, if the component type is discrete, the
- predefined relational operators; if the component type is boolean, the
- predefined logical operators are also included.
-
- 16 (48) A component of an array can be named with an indexed_component. A
- value of an array type can be specified with an array_aggregate, unless
- the array type is limited. For a one-dimensional array type, a slice of
- the array can be named; also, string literals are defined if the
- component type is a character type.
-
-
- Examples
-
- 17 Examples (using arrays declared in the examples of subclause 3.6.1):
-
- 18 -- Filter'First = 0 Filter'Last = 31 Filter'Length =\
- 32
- -- Rectangle'Last(1) = 20 Rectangle'Last(2) = 30
-
-
-
- 3.6.3 String Types
-
- Static Semantics
-
- 1 {string type} A one-dimensional array type whose component type is a
- character type is called a string type.
-
- 2 [There are two predefined string types, String and Wide_String, each
- indexed by values of the predefined subtype Positive; these are declared in
- the visible part of package Standard:
-
- 3 subtype Positive is Integer range 1 .. Integer'Last;
-
- 4 type String is array(Positive range <>) of Character;
- type Wide_String is array(Positive range <>) of Wide_Character;
-
- ]
-
-
- NOTES
- 5 (49) String literals (see 2.6 and 4.2) are defined for all string types.
- The concatenation operator & is predefined for string types, as for all
- nonlimited one-dimensional array types. The ordering operators <, <=,
- >, and >= are predefined for string types, as for all one-dimensional
- discrete array types; these ordering operators correspond to
- lexicographic order (see 4.5.2).
-
-
- Examples
-
- 6 Examples of string objects:
-
- 7 Stars : String(1 .. 120) := (1 .. 120 => '*' );
- Question : constant String := "How many characters?";
- -- Question'First = 1, Ques\
- tion'Last = 20
- -- Question'Length = 20 (th\
- e number of characters)
-
- 8 Ask_Twice : String := Question & Question; -- constrained to (1..40)
- Ninety_Six : constant Roman := "XCVI"; -- see 3.5.2 and 3.6
-
-
- Inconsistencies With Ada 83
-
- 8.a {inconsistencies with Ada 83} The declaration of Wide_String in
- Standard hides a use-visible declaration with the same defining_
- identifier. In rare cases, this might result in an inconsistency
- between Ada 83 and Ada 9X.
-
- Incompatibilities With Ada 83
-
- 8.b {incompatibilities with Ada 83} Because both String and Wide_
- String are always directly visible, an expression like
-
- 8.c "a" < "bc"
-
- 8.d is now ambiguous, whereas in Ada 83 both string literals could
- be resolved to type String.
-
- Extensions to Ada 83
-
- 8.e {extensions to Ada 83} The type Wide_String is new (though it
- was approved by ARG for Ada 83 compilers as well).
-
- Wording Changes From Ada 83
-
- 8.f We define the term string type as a natural analogy to the term
- character type.
-
-
-
- 3.7 Discriminants
-
- 1 [{discriminant} {type parameter: see discriminant} {parameter: see also
- discriminant} A composite type (other than an array type) can have
- discriminants, which parameterize the type. A known_discriminant_part
- specifies the discriminants of a composite type. A discriminant of an object
- is a component of the object, and is either of a discrete type or an access
- type. An unknown_discriminant_part in the declaration of a partial view of a
- type specifies that the discriminants of the type are unknown for the given
- view; all subtypes of such a partial view are indefinite subtypes.]
-
- 1.a Glossary entry: {Discriminant} A discriminant is a parameter
- of a composite type. It can control, for example, the bounds of a
- component of the type if that type is an array type. A discriminant
- of a task type can be used to pass data to a task of the type upon
- creation.
-
- 1.b Discussion: {unknown discriminants [partial]} {discriminants
- [unknown]} A type, and all of its subtypes, have unknown
- discriminants when the number or names of the discriminants, if any,
- are unknown at the point of the type declaration. A discriminant_
- part of (<>) is used to indicate unknown discriminants.
-
-
- Syntax
-
- 2 discriminant_part ::= unknown_discriminant_part | known_discriminant_part
-
- 3 unknown_discriminant_part ::= (<>)
-
- 4 known_discriminant_part ::=
- (discriminant_specification {; discriminant_specification})
-
- 5 discriminant_specification ::=
- defining_identifier_list : subtype_mark [:= default_expression]
- | defining_identifier_list : access_definition [:= default_expression]
-
- 6 default_expression ::= expression
-
-
- Name Resolution Rules
-
- 7 {expected type [discriminant default_expression]} The expected type for
- the default_expression of a discriminant_specification is that of the
- corresponding discriminant.
-
-
- Legality Rules
-
- 8 A known_discriminant_part is only permitted in a declaration for a
- composite type that is not an array type [(this includes generic formal
- types)]; {discriminated type} a type declared with a known_discriminant_part
- is called a discriminated type, as is a type that inherits (known)
- discriminants.
-
- 8.a Implementation Note: Discriminants on array types were
- considered, but were omitted to ease (existing) implementations.
-
- 8.b Discussion: Note that the above definition for ``discriminated
- type'' does not include types declared with an unknown_discriminant_
- part. This seems consistent with Ada 83, where such types (in a
- generic formal part) would not be considered discriminated types.
- Furthermore, the full type for a type with unknown discriminants need
- not even be composite, much less have any discriminants.
-
- 9 The subtype of a discriminant may be defined by a subtype_mark, in which
- case the subtype_mark shall denote a discrete or access subtype, or it may be
- defined by an access_definition [(in which case the subtype_mark of the
- access_definition may denote any kind of subtype)]. {access discriminant} A
- discriminant that is defined by an access_definition is called an access
- discriminant and is of an anonymous general access-to-variable type whose
- designated subtype is denoted by the subtype_mark of the access_definition.
-
- 9.a Reason: In an earlier version of Ada 9X, we allowed access
- discriminants on nonlimited types, but this created unpleasant
- complexities. It turned out to be simpler and more uniform to allow
- discriminants of a named access type on any discriminated type, and
- keep access discriminants just for limited types.
-
- 9.b Note that discriminants of a named access type are not
- considered ``access discriminants.'' Similarly, ``access parameter''
- only refers to a formal parameter defined by an access_definition.
-
- 10 A discriminant_specification for an access discriminant shall appear
- only in the declaration for a task or protected type, or for a type with the
- reserved word limited in its [(full)] definition or in that of one of its
- ancestors. In addition to the places where Legality Rules normally apply
- (see 12.3), this rule applies also in the private part of an instance of a
- generic unit.
-
- 10.a Discussion: This rule implies that a type can have an access
- discriminant if the type is limited, but not if the only reason it's
- limited is because of a limited component. Compare with the
- definition of limited type in 7.5.
-
- 10.b Ramification: It is a consequence of this rule that only a
- return-by-reference type can have an access discriminant (see 6.5).
- This is important to avoid dangling references to local variables.
-
- 10.c Reason: We also considered the following rules:
-
- 10.d If a type has an access discriminant, this automatically
- makes it limited, just like having a limited component
- automatically makes a type limited. This was rejected
- because it decreases program readability, and because it
- seemed error prone (two bugs in a previous version of the
- RM9X were attributable to this rule).
-
- 10.e A type with an access discriminant shall be limited.
- This is equivalent to the rule we actually chose, except
- that it allows a type to have an access discriminant if
- it is limited just because of a limited component. For
- example, any record containing a task would be allowed to
- have an access discriminant, whereas the actual rule
- requires ``limited record''. This rule was also rejected
- due to readability concerns, and because would interact
- badly with the rules for limited types that ``become
- nonlimited''.
-
- 11 Default_expressions shall be provided either for all or for none of the
- discriminants of a known_discriminant_part. No default_expressions are
- permitted in a known_discriminant_part in a declaration of a tagged type [or
- a generic formal type].
-
- 11.a Reason: The all-or-none rule is related to the rule that a
- discriminant constraint shall specify values for all discriminants.
- One could imagine a different rule that allowed a constraint to
- specify only some of the discriminants, with the others provided by
- default. Having defaults for discriminants has a special
- significance -- it allows objects of the type to be unconstrained,
- with the discriminants alterable as part of assigning to the object.
-
- 11.b Defaults for discriminants of tagged types are disallowed so
- that every object of a tagged type is constrained, either by an
- explicit constraint, or by its initial discriminant values.
- {94-4858.a} This substantially simplifies the semantic rules and the
- implementation of inherited dispatching operations. For generic
- formal types, the restriction simplifies the type matching rules. If
- one simply wants a "default" value for the discriminants, a
- constrained subtype can be declared for future use.
-
- 12 For a type defined by a derived_type_definition, if a known_
- discriminant_part is provided in its declaration, then:
-
- 13 The parent subtype shall be constrained;
-
- 14 If the parent type is not a tagged type, then each discriminant
- of the derived type shall be used in the constraint defining the
- parent subtype;
-
- 14.a Implementation Note: This ensures that the new discriminant can
- share storage with an existing discriminant.
-
- 15 If a discriminant is used in the constraint defining the parent
- subtype, the subtype of the discriminant shall be statically
- compatible (see 4.9.1) with the subtype of the corresponding
- parent discriminant.
-
- 15.a Reason: This ensures that on conversion (or extension via an
- extension aggregate) to a distantly related type, if the
- discriminants satisfy the target type's requirements they
- satisfy all the intermediate types' requirements as well.
-
- 15.b Ramification: There is no requirement that the new discriminant
- have the same (or any) default_expression as the parent's
- discriminant.
-
- 16 The type of the default_expression, if any, for an access discriminant
- shall be convertible to the anonymous access type of the discriminant (see
- 4.6). {convertible [required]}
-
- 16.a Ramification: This requires convertibility of the designated
- subtypes.
-
-
- Static Semantics
-
- 17 A discriminant_specification declares a discriminant; the subtype_mark
- denotes its subtype unless it is an access discriminant, in which case the
- discriminant's subtype is the anonymous access-to-variable subtype defined by
- the access_definition.
-
- 18 [For a type defined by a derived_type_definition, each discriminant of
- the parent type is either inherited, constrained to equal some new
- discriminant of the derived type, or constrained to the value of an
- expression.] {corresponding discriminants} When inherited or constrained to
- equal some new discriminant, the parent discriminant and the discriminant of
- the derived type are said to correspond. Two discriminants also correspond
- if there is some common discriminant to which they both correspond. A
- discriminant corresponds to itself as well. {specified discriminant} If a
- discriminant of a parent type is constrained to a specific value by a
- derived_type_definition, then that discriminant is said to be specified by
- that derived_type_definition.
-
- 18.a Ramification: The correspondence relationship is transitive,
- symmetric, and reflexive. That is, if A corresponds to B, and B
- corresponds to C, then A, B, and C each corresponds to A, B, and C in
- all combinations.
-
- 19 {depend on a discriminant (for a constraint or component_definition)} A
- constraint that appears within the definition of a discriminated type depends
- on a discriminant of the type if it names the discriminant as a bound or
- discriminant value. A component_definition depends on a discriminant if its
- constraint depends on the discriminant, or on a discriminant that corresponds
- to it.
-
- 19.a Ramification: A constraint in a task_body is not considered
- to depend on a discriminant of the task type, even if it names it.
- It is only the constraints in the type definition itself that are
- considered dependents. Similarly for protected types.
-
- 20 {depend on a discriminant (for a component)} A component depends on a
- discriminant if:
- 21 Its component_definition depends on the discriminant; or
-
- 21.a Ramification: A component does not depend on a discriminant
- just because its default_expression refers to the discriminant.
-
- 22 It is declared in a variant_part that is governed by the
- discriminant; or
-
- 23 It is a component inherited as part of a derived_type_definition,
- and the constraint of the parent_subtype_indication depends on
- the discriminant; or
-
- 23.a Reason: When the parent subtype depends on a discriminant, the
- parent part of the derived type is treated like a
- discriminant-dependent component.
-
- 23.b Ramification: Because of this rule, we don't really need to
- worry about ``corresponding'' discriminants, since all the
- inherited components will be discriminant-dependent if there is
- a new known_discriminant_part whose discriminants are used to
- constrain the old discriminants.
-
- 24 It is a subcomponent of a component that depends on the
- discriminant.
-
- 24.a Reason: The concept of discriminant-dependent (sub)components
- is primarily used in various rules that disallow renaming or 'Access,
- or specify that certain discriminant-changing assignments are
- erroneous. The goal is to allow implementations to move around or
- change the size of discriminant-dependent subcomponents upon a
- discriminant-changing assignment to an enclosing object. The above
- definition specifies that all subcomponents of a discriminant-
- dependent component or parent part are themselves discriminant-
- dependent, even though their presence or size does not in fact depend
- on a discriminant. This is because it is likely that they will move
- in a discriminant-changing assignment if they are a component of one
- of several discriminant-dependent parts of the same record.
-
- 25 Each value of a discriminated type includes a value for each component
- of the type that does not depend on a discriminant[; this includes the
- discriminants themselves]. The values of discriminants determine which other
- component values are present in the value of the discriminated type.
-
- 25.a To be honest: Which values are present might depend on
- discriminants of some ancestor type that are constrained in an
- intervening derived_type_definition. That's why we say "values of
- discriminants" instead of "values of the discriminants" -- a subtle
- point.
-
- 26 {known discriminants} {discriminants (known)} {constrained (subtype)}
- {unconstrained (subtype)} A type declared with a known_discriminant_part is
- said to have known discriminants; its first subtype is unconstrained.
- {unknown discriminants} {discriminants (unknown)} A type declared with an
- unknown_discriminant_part is said to have unknown discriminants. A type
- declared without a discriminant_part has no discriminants, unless it is a
- derived type; if derived, such a type has the same sort of discriminants
- (known, unknown, or none) as its parent (or ancestor) type. A tagged
- class-wide type also has unknown discriminants. {class-wide type}
- {indefinite subtype} [Any subtype of a type with unknown discriminants is an
- unconstrained and indefinite subtype (see 3.2 and 3.3).] {94-4610.a}
-
- 26.a Discussion: An unknown_discriminant_part ``(<>)'' is only
- permitted in the declaration of a (generic or nongeneric) private
- type, private extension, or formal derived type. Hence, only such
- types, descendants thereof, and class-wide types can have unknown
- discriminants. An unknown_discriminant_part is used to indicate that
- the corresponding actual or full type might have discriminants
- without defaults, or be an unconstrained array subtype. Tagged
- class-wide types are also considered to have unknown discriminants
- because discriminants can be added by type extensions, so the total
- number of discriminants of any given value of a tagged class-wide
- type is not known at compile time.
-
- 26.b A subtype with unknown discriminants is indefinite, and hence
- an object of such a subtype needs explicit initialization. If the
- subtype is limited, no (stand-alone) objects can be declared since
- initialization is not permitted (though formal parameters are
- permitted, and objects of the actual/full type will generally be
- declarable). A limited private type with unknown discriminants is
- ``extremely'' limited; such a type is useful for keeping complete
- control over object creation within the package declaring the type.
-
- 26.c A partial view of a type might have unknown discriminants,
- while the full view of the same type might have known, unknown, or no
- discriminants,
-
-
- Dynamic Semantics
-
- 27 An access_definition is elaborated when the value of a corresponding
- access discriminant is defined, either by evaluation of its default_
- expression or by elaboration of a discriminant_constraint. [The elaboration
- of an access_definition creates the anonymous access type. When the
- expression defining the access discriminant is evaluated, it is converted to
- this anonymous access type (see 4.6).] {implicit subtype conversion [access
- discriminant]}
-
- 27.a Ramification: This conversion raises Constraint_Error if the
- initial value is null, or, for an object created by an allocator of
- an access type T, if the initial value is an access parameter that
- designates a view whose accessibility level is deeper than that of
- T. {94-4715.a}
-
-
- NOTES
- 28 (50) If a discriminated type has default_expressions for its
- discriminants, then unconstrained variables of the type are permitted,
- and the values of the discriminants can be changed by an assignment to
- such a variable. If defaults are not provided for the discriminants,
- then all variables of the type are constrained, either by explicit
- constraint or by their initial value; the values of the discriminants of
- such a variable cannot be changed after initialization.
-
- 28.a Discussion: This connection between discriminant defaults and
- unconstrained variables can be a source of confusion. For Ada 9X, we
- considered various ways to break the connection between defaults and
- unconstrainedness, but ultimately gave up for lack of a sufficiently
- simple and intuitive alternative.
-
- 28.b {mutable} An unconstrained discriminated subtype with defaults is
- called a mutable subtype, and a variable of such a subtype is called
- a mutable variable, because the discriminants of such a variable can
- change. There are no mutable arrays (that is, the bounds of an array
- object can never change), because there is no way in the language to
- define default values for the bounds. Similarly, there are no
- mutable class-wide subtypes, because there is no way to define the
- default tag, and defaults for discriminants are not allowed in the
- tagged case. Mutable tags would also require a way for the maximum
- possible size of such a class-wide subtype to be known. (In some
- implementations, all mutable variables are allocated with the maximum
- possible size. This approach is appropriate for real-time
- applications where implicit use of the heap is inappropriate.)
- {94-4799.a} {94-4801.a} {94-4806.a} {94-4874.a} {94-4882.a}
-
- 29 (51) The default_expression for a discriminant of a type is evaluated
- when an object of an unconstrained subtype of the type is created.
-
- 30 (52) Assignment to a discriminant of an object (after its
- initialization) is not allowed, since the name of a discriminant is a
- constant; neither assignment_statements nor assignments inherent in
- passing as an in out or out parameter are allowed. Note however that
- the value of a discriminant can be changed by assigning to the enclosing
- object, presuming it is an unconstrained variable.
-
- 30.a Discussion: An unknown_discriminant_part is permitted only in the
- declaration of a private type (including generic formal private),
- private extension, or generic formal derived type. These are the
- things that will have a corresponding completion or generic actual,
- which will either define the discriminants, or say there are none.
- The (<>) indicates that the actual/full subtype might be an
- indefinite subtype. An unknown_discriminant_part is not permitted in
- a normal untagged derived type declaration, because there is no
- separate full type declaration for such a type. Note that (<>)
- allows unconstrained array bounds; those are somewhat like
- undefaulted discriminants.
-
- 30.b For a derived type, either the discriminants are inherited as is,
- or completely respecified in a new discriminant_part. In this latter
- case, each discriminant of the parent type shall be constrained,
- either to a specific value, or to equal one of the new discriminants.
- Constraining a parent type's discriminant to equal one of the new
- discriminants is like a renaming of the discriminant, except that the
- subtype of the new discriminant can be more restrictive than that of
- the parent's one. In any case, the new discriminant can share
- storage with the parent's discriminant.
-
- 31 (53) A discriminant that is of a named access type is not called an
- access discriminant; that term is used only for discriminants defined by
- an access_definition.
-
-
- Examples
-
- 32 Examples of discriminated types:
-
- 33 type Buffer(Size : Buffer_Size := 100) is -- see 3.5.4
- record
- Pos : Buffer_Size := 0;
- Value : String(1 .. Size);
- end record;
-
- 34 type Matrix_Rec(Rows, Columns : Integer) is
- record
- Mat : Matrix(1 .. Rows, 1 .. Columns); -- see 3.6
- end record;
-
- 35 type Square(Side : Integer) is new Matrix_Rec(Rows => Side, Columns => Side\
- );
-
- 36 type Double_Square(Number : Integer) is
- record
- Left : Square(Number);
- Right : Square(Number);
- end record;
-
- 37 type Item(Number : Positive) is
- record
- Content : Integer;
- -- no component depends on the discriminant
- end record;
- Extensions to Ada 83
-
- 37.a {extensions to Ada 83} The syntax for a discriminant_
- specification is modified to allow an access discriminant, with a
- type specified by an access_definition (see 3.10).
-
- 37.b Discriminants are allowed on all composite types other than
- array types.
-
- 37.c Discriminants may be of an access type.
-
- Wording Changes From Ada 83
-
- 37.d Discriminant_parts are not elaborated, though an access_
- definition is elaborated when the discriminant is initialized.
-
-
-
- 3.7.1 Discriminant Constraints
-
- 1 A discriminant_constraint specifies the values of the discriminants for a
- given discriminated type.
-
-
- Language Design Principles
-
- 1.a The rules in this clause are intentionally parallel to those
- given in Record Aggregates.
-
- Syntax
-
- 2 discriminant_constraint ::=
- (discriminant_association {, discriminant_association})
-
- 3 discriminant_association ::=
- [discriminant_selector_name {| discriminant_selector_name} =>] expression
-
- 4 {named discriminant association} A discriminant_association is said
- to be named if it has one or more discriminant_selector_names;
- {positional discriminant association} it is otherwise said to be
- positional. In a discriminant_constraint, any positional associations
- shall precede any named associations.
-
-
- Name Resolution Rules
-
- 5 Each selector_name of a named discriminant_association shall resolve to
- denote a discriminant of the subtype being constrained; {associated
- discriminants (of a named discriminant_association)} the discriminants so
- named are the associated discriminants of the named association. {associated
- discriminants (of a positional discriminant_association)} For a positional
- association, the associated discriminant is the one whose discriminant_
- specification occurred in the corresponding position in the known_
- discriminant_part that defined the discriminants of the subtype being
- constrained.
-
- 6 {expected type [discriminant_association expression]} The expected type
- for the expression in a discriminant_association is that of the associated
- discriminant(s).
-
-
- Legality Rules
-
- 7 A discriminant_constraint is only allowed in a subtype_indication whose
- subtype_mark denotes either an unconstrained discriminated subtype, or an
- unconstrained access subtype whose designated subtype is an unconstrained
- discriminated subtype.
-
- 8 A named discriminant_association with more than one selector_name is
- allowed only if the named discriminants are all of the same type. A
- discriminant_constraint shall provide exactly one value for each discriminant
- of the subtype being constrained.
-
- 9 The expression associated with an access discriminant shall be of a type
- convertible to the anonymous access type. {convertible [required]}
-
- 9.a Ramification: This implies both convertibility of designated
- types, and static accessibility. This implies that if an object of
- type T with an access discriminant is created by an allocator for an
- access type A, then it requires that the type of the expression
- associated with the access discriminant have an accessibility level
- that is not statically deeper than that of A. This is to avoid
- dangling references. {94-4715.a}
-
-
- Dynamic Semantics
-
- 10 {compatibility [discriminant constraint with a subtype]} A discriminant_
- constraint is compatible with an unconstrained discriminated subtype if each
- discriminant value belongs to the subtype of the corresponding discriminant.
-
- 10.a Ramification: The "dependent compatibility check" has been
- eliminated in Ada 9X. Any checking on subcomponents is performed
- when (and if) an object is created.
-
- 10.b Discussion: There is no need to define compatibility with a
- constrained discriminated subtype, because one is not allowed to
- constrain it again.
-
- 11 {satisfies [a discriminant constraint]} A composite value satisfies a
- discriminant constraint if and only if each discriminant of the composite
- value has the value imposed by the discriminant constraint.
-
- 12 {elaboration [discriminant_constraint]} For the elaboration of a
- discriminant_constraint, the expressions in the discriminant_associations are
- evaluated in an arbitrary order and converted to the type of the associated
- discriminant (which might raise Constraint_Error -- see 4.6); the expression
- of a named association is evaluated (and converted) once for each associated
- discriminant. {implicit subtype conversion [discriminant values]} The result
- of each evaluation and conversion is the value imposed by the constraint for
- the associated discriminant.
-
- 12.a Reason: We convert to the type, not the subtype, so that the
- definition of compatibility of discriminant constraints is not
- vacuous.
-
-
- NOTES
- 13 (54) The rules of the language ensure that a discriminant of an object
- always has a value, either from explicit or implicit initialization.
-
- 13.a Discussion: Although it is illegal to constrain a class-wide
- tagged subtype, it is possible to have a partially constrained
- class-wide subtype: If the subtype S is defined by T(A => B), then
- S'Class is partially constrained in the sense that objects of subtype
- S'Class have to have discriminants corresponding to A equal to B, but
- there can be other discriminants defined in extensions that are not
- constrained to any particular value.
-
-
- Examples
-
- 14 Examples (using types declared above in clause 3.7):
-
- 15 Large : Buffer(200); -- constrained, always 200 characters
- -- (explicit discriminant value)
- Message : Buffer; -- unconstrained, initially 100 characters
- -- (default discriminant value)
- Basis : Square(5); -- constrained, always 5 by 5
- Illegal : Square; -- illegal, a Square has to be constrained
-
-
- Inconsistencies With Ada 83
-
- 15.a {inconsistencies with Ada 83} Dependent compatibility checks
- are no longer performed on subtype declaration. Instead they are
- deferred until object creation (see 3.3.1). This is upward
- compatible for a program that does not raise Constraint_Error.
-
- Wording Changes From Ada 83
-
- 15.b Everything in RM83-3.7.2(7-12), which specifies the initial
- values for discriminants, is now redundant with 3.3.1, 6.4.1, 8.5.1,
- and 12.4. Therefore, we don't repeat it here. Since the material is
- largely intuitive, but nevertheless complicated to state formally, it
- doesn't seem worth putting it in a "NOTE."
-
-
-
- 3.7.2 Operations of Discriminated Types
-
- 1 [If a discriminated type has default_expressions for its discriminants,
- then unconstrained variables of the type are permitted, and the discriminants
- of such a variable can be changed by assignment to the variable. For a
- formal parameter of such a type, an attribute is provided to determine
- whether the corresponding actual parameter is constrained or unconstrained.]
-
-
- Static Semantics
-
- 2 For a prefix A that is of a discriminated type [(after any implicit
- dereference)], the following attribute is defined:
-
- 3 A'Constrained
- Yields the value True if A denotes a constant, a value, or a
- constrained variable, and False otherwise.
-
- 3.a Implementation Note: This attribute is primarily used on parameters,
- to determine whether the discriminants can be changed as part of an
- assignment. The Constrained attribute is statically True for in
- parameters. For in out and out parameters of a discriminated type,
- the value of this attribute needs to be passed as an implicit
- parameter, in general. However, if the type does not have defaults
- for its discriminants, the attribute is statically True, so no
- implicit parameter is needed. Parameters of a limited type with
- defaulted discriminants need this implicit parameter, unless there
- are no nonlimited views, because they might be passed to a subprogram
- whose body has visibility on a nonlimited view of the type, and hence
- might be able to assign to the object and change its discriminants.
-
-
- Erroneous Execution
-
- 4 {erroneous execution} The execution of a construct is erroneous if the
- construct has a constituent that is a name denoting a subcomponent that
- depends on discriminants, and the value of any of these discriminants is
- changed by this execution between evaluating the name and the last use
- (within this execution) of the subcomponent denoted by the name.
- 4.a Ramification: This rule applies to assignment_statements,
- calls (except when the discriminant-dependent subcomponent is an in
- parameter passed by copy), indexed_components, and slices. Ada 83
- only covered the first two cases. AI-00585 pointed out the situation
- with the last two cases. The cases of object_renaming_declarations
- and generic formal in out objects are handled differently, by
- disallowing the situation at compile time.
-
-
- Extensions to Ada 83
-
- 4.b {extensions to Ada 83} For consistency with other attributes,
- we are allowing the prefix of Constrained to be a value as well as an
- object of a discriminated type, and also an implicit dereference.
- These extensions are not important capabilities, but there seems no
- reason to make this attribute different from other similar
- attributes. We are curious what most Ada 83 compilers do with
- F(1).X'Constrained.
-
- 4.c We now handle in a general way the cases of erroneousness
- identified by AI-585, where the prefix of an indexed_component or
- slice is discriminant-dependent, and the evaluation of the index or
- discrete range changes the value of a discriminant.
-
- Wording Changes From Ada 83
-
- 4.d We have moved all discussion of erroneous use of names that
- denote discriminant-dependent subcomponents to this subclause. In
- Ada 83, it used to appear separately under assignment_statements and
- subprogram calls.
-
-
-
- 3.8 Record Types
-
- 1 {record} {record type} A record object is a composite object consisting
- of named components. The value of a record object is a composite value
- consisting of the values of the components. {structure: see record type}
-
-
- Syntax
-
- 2 record_type_definition ::= [[abstract] tagged] [limited] record_definition
-
- 3 record_definition ::=
- record
- component_list
- end record
- | null record
-
- 4 component_list ::=
- component_item {component_item}
- | {component_item} variant_part
- | null;
-
- 5 component_item ::= component_declaration | representation_clause
-
- 6 component_declaration ::=
- defining_identifier_list : component_definition [:= default_expression];
-
-
- Name Resolution Rules
-
- 7 {expected type [component_declaration default_expression]} The expected
- type for the default_expression, if any, in a component_declaration is the
- type of the component.
-
-
- Legality Rules
-
- 8 A default_expression is not permitted if the component is of a limited
- type.
-
- 9 {components [of a record type]} Each component_declaration declares a
- component of the record type. Besides components declared by component_
- declarations, the components of a record type include any components declared
- by discriminant_specifications of the record type declaration. [The
- identifiers of all components of a record type shall be distinct.]
-
- 9.a Proof: The identifiers of all components of a record type have
- to be distinct because they are all declared immediately within the
- same declarative region. See Section 8.
-
- 10 Within a type_declaration, a name that denotes a component, protected
- subprogram, or entry of the type is allowed only in the following cases:
- {94-4663.a} {94-4664.a}
-
- 11 A name that denotes any component, protected subprogram, or entry
- is allowed within a representation item that occurs within the
- declaration of the composite type.
-
- 12 A name that denotes a noninherited discriminant is allowed within
- the declaration of the type, but not within the discriminant_
- part. If the discriminant is used to define the constraint of a
- component, the bounds of an entry family, or the constraint of
- the parent subtype in a derived_type_definition then its name
- shall appear alone as a direct_name (not as part of a larger
- expression or expanded name).
-
- 12.a Reason: This restriction simplifies implementation, and allows
- the outer discriminant and the inner discriminant or bound to
- possibly share storage.
-
- 12.b Ramification: Other rules prevent such a discriminant from
- being an inherited one.
-
- A discriminant shall not be used to define the constraint of a
- scalar component.
-
- 12.c Reason: This restriction is inherited from Ada 83. The
- restriction is not really necessary from a language design point
- of view, but we did not remove it, in order to avoid unnecessary
- changes to existing compilers.
-
- 12.d Discussion: Note that a discriminant can be used to define the
- constraint for a component that is of an access-to-composite
- type.
-
- 12.e Reason: The above rules, and a similar one in 6.1 for formal
- parameters, are intended to allow initializations of components
- or parameters to occur in an arbitrary order -- whatever order
- is most efficient, since one default_expression cannot depend on
- the value of another one. It also prevent circularities.
-
- 12.f Ramification: Inherited discriminants are not allowed to be
- denoted, except within representation items. However, the
- discriminant_selector_name of the parent subtype_indication is
- allowed to denote a discriminant of the parent.
-
- 13 If the name of the current instance of a type (see 8.6) is used to
- define the constraint of a component, then it shall appear as a direct_name
- that is the prefix of an attribute_reference whose result is of an access
- type, and the attribute_reference shall appear alone.
-
- 13.a Reason: This rule allows T'Access or T'Unchecked_Access, but
- disallows, for example, a range constraint (1..T'Size). Allowing
- things like (1..T'Size) would mean that a per-object constraint could
- affect the size of the object, which would be bad.
-
-
- Static Semantics
-
- 14 {nominal subtype [of a record component]} The component_definition of a
- component_declaration defines the (nominal) subtype of the component. If the
- reserved word aliased appears in the component_definition, then the component
- is aliased (see 3.10).
-
- 14.a Ramification: In this case, the nominal subtype cannot be an
- unconstrained discriminated subtype. See 3.6.
-
- 15 {null record} If the component_list of a record type is defined by the
- reserved word null and there are no discriminants, then the record type has
- no components and all records of the type are null records. A record_
- definition of null record is equivalent to record null; end record.
-
- 15.a Ramification: This short-hand is available both for declaring
- a record type and a record extension -- see 3.9.1.
-
-
- Dynamic Semantics
-
- 16 {elaboration [record_type_definition]} The elaboration of a record_type_
- definition creates the record type and its first subtype, and consists of the
- elaboration of the record_definition. {elaboration [record_definition]} The
- elaboration of a record_definition consists of the elaboration of its
- component_list, if any.
-
- 17 {elaboration [component_list]} The elaboration of a component_list
- consists of the elaboration of the component_items and variant_part, if any,
- in the order in which they appear. {elaboration [component_declaration]} The
- elaboration of a component_declaration consists of the elaboration of the
- component_definition.
-
- 17.a Discussion: If the defining_identifier_list has more than one
- defining_identifier, we presume here that the transformation
- explained in 3.3.1 has already taken place. Alternatively, we could
- say that the component_definition is elaborated once for each
- defining_identifier in the list.
-
- 18 {per-object expression} {per-object constraint} {entry index subtype}
- Within the definition of a composite type, if a component_definition or
- discrete_subtype_definition (see 9.5.2) includes a name that denotes a
- discriminant of the type, or that is an attribute_reference whose prefix
- denotes the current instance of the type, the expression containing the name
- is called a per-object expression, and the constraint being defined is called
- a per-object constraint.
-
- 18.a Discussion: The evaluation of other expressions that appear
- in component_definitions and discrete_subtype_definitions is per-
- formed when the type definition is elaborated. The evaluation of
- expressions that appear as default_expressions is postponed until an
- object is created. Expressions in representation items that appear
- within a composite type definition are evaluated according to the
- rules of the particular representation item.
-
- {elaboration [component_definition]} For the elaboration of a component_
- definition of a component_declaration, if the constraint of the subtype_
- indication is not a per-object constraint, then the subtype_indication is
- elaborated. On the other hand, if the constraint is a per-object constraint,
- then the elaboration consists of the evaluation of any included expression
- that is not part of a per-object expression.
-
-
- NOTES
- 19 (55) A component_declaration with several identifiers is equivalent to a
- sequence of single component_declarations, as explained in 3.3.1.
-
- 20 (56) The default_expression of a record component is only evaluated upon
- the creation of a default-initialized object of the record type
- (presuming the object has the component, if it is in a variant_part --
- see 3.3.1).
-
- 21 (57) The subtype defined by a component_definition (see 3.6) has to be a
- definite subtype.
-
- 22 (58) If a record type does not have a variant_part, then the same
- components are present in all values of the type.
-
- 23 (59) A record type is limited if it has the reserved word limited in its
- definition, or if any of its components are limited (see 7.5).
-
- 24 (60) {predefined operations [of a record type]} The predefined
- operations of a record type include membership tests, qualification, and
- explicit conversion. If the record type is nonlimited, they also
- include assignment and the predefined equality operators.
-
- 25 (61) A component of a record can be named with a selected_component. A
- value of a record can be specified with a record_aggregate, unless the
- record type is limited.
-
-
- Examples
-
- 26 Examples of record type declarations:
-
- 27 type Date is
- record
- Day : Integer range 1 .. 31;
- Month : Month_Name;
- Year : Integer range 0 .. 4000;
- end record;
-
- 28 type Complex is
- record
- Re : Real := 0.0;
- Im : Real := 0.0;
- end record;
-
- 29 Examples of record variables:
-
- 30 Tomorrow, Yesterday : Date;
- A, B, C : Complex;
-
- 31 -- both components of A, B, and C are implicitly initialized to zero
-
-
- Extensions to Ada 83
-
- 31.a {extensions to Ada 83} The syntax rule for component_
- declaration is modified to use component_definition (instead of
- component_subtype_definition). The effect of this change is to allow
- the reserved word aliased before the component_subtype_definition.
-
- 31.b A short-hand is provided for defining a null record type (and
- a null record extension), as these will be more common for abstract
- root types (and derived types without additional components).
-
- 31.c The syntax rule for record_type_definition is modified to
- allow the reserved words tagged and limited. Tagging is new.
- Limitedness is now orthogonal to privateness. In Ada 83 the syntax
- implied that limited private was sort of more private than private.
- However, limitedness really has nothing to do with privateness;
- limitedness simply indicates the lack of assignment capabilities, and
- makes perfect sense for nonprivate types such as record types.
-
- Wording Changes From Ada 83
-
- 31.d The syntax rules now allow representation_clauses to appear in
- a record_definition. This is not a language extension, because
- Legality Rules prevent all language-defined representation clauses
- from appearing there. However, an implementation-defined attribute_
- definition_clause could appear there. The reason for this change is
- to allow the rules for representation_clauses and representation
- pragmas to be as similar as possible.
-
-
-
- 3.8.1 Variant Parts and Discrete Choices
-
- 1 A record type with a variant_part specifies alternative lists of
- components. Each variant defines the components for the value or values of
- the discriminant covered by its discrete_choice_list.
-
- 1.a Discussion: {cover a value [distributed]} Discrete_choice_
- lists and discrete_choices are said to cover values as defined below;
- which discrete_choice_list covers a value determines which of various
- alternatives is chosen. These are used in variant_parts, array_
- aggregates, and case_statements.
-
-
- Language Design Principles
-
- 1.b The definition of ``cover'' in this subclause and the rules
- about discrete choices are designed so that they are also appropriate
- for array aggregates and case statements.
-
- 1.c The rules of this subclause intentionally parallel those for
- case statements.
-
- Syntax
-
- 2 variant_part ::=
- case discriminant_direct_name is
- variant
- {variant}
- end case;
-
- 3 variant ::=
- when discrete_choice_list =>
- component_list
-
- 4 discrete_choice_list ::= discrete_choice {| discrete_choice}
-
- 5 discrete_choice ::= expression | discrete_range | others
-
-
- Name Resolution Rules
-
- 6 {discriminant (of a variant_part)} The discriminant_direct_name shall
- resolve to denote a discriminant (called the discriminant of the variant_
- part) specified in the known_discriminant_part of the full_type_declaration
- that contains the variant_part. {expected type [variant_part discrete_
- choice]} The expected type for each discrete_choice in a variant is the type
- of the discriminant of the variant_part.
-
- 6.a Ramification: A full_type_declaration with a variant_part has
- to have a (new) known_discriminant_part; the discriminant of the
- variant_part cannot be an inherited discriminant.
-
-
- Legality Rules
-
- 7 The discriminant of the variant_part shall be of a discrete type.
-
- 7.a Ramification: It shall not be of an access type, named or
- anonymous.
-
- 8 The expressions and discrete_ranges given as discrete_choices in a
- variant_part shall be static. The discrete_choice others shall appear alone
- in a discrete_choice_list, and such a discrete_choice_list, if it appears,
- shall be the last one in the enclosing construct.
-
- 9 {cover a value [by a discrete_choice]} A discrete_choice is defined to
- cover a value in the following cases:
-
- 10 A discrete_choice that is an expression covers a value if the
- value equals the value of the expression converted to the
- expected type.
-
- 11 A discrete_choice that is a discrete_range covers all values
- (possibly none) that belong to the range.
-
- 12 The discrete_choice others covers all values of its expected type
- that are not covered by previous discrete_choice_lists of the
- same construct.
-
- 12.a Ramification: For case_statements, this includes values outside
- the range of the static subtype (if any) to be covered by the
- choices. It even includes values outside the base range of the
- case expression's type, since values of numeric types (and
- undefined values of any scalar type?) can be outside their base
- range.
-
- 13 {cover a value [by a discrete_choice_list]} A discrete_choice_list
- covers a value if one of its discrete_choices covers the value.
-
- 14 The possible values of the discriminant of a variant_part shall be
- covered as follows:
-
- 15 If the discriminant is of a static constrained scalar subtype,
- then each non-others discrete_choice shall cover only values in
- that subtype, and each value of that subtype shall be covered by
- some discrete_choice [(either explicitly or by others)];
-
- 16 If the type of the discriminant is a descendant of a generic
- formal scalar type then the variant_part shall have an others
- discrete_choice;
-
- 16.a Reason: The base range is not known statically in this case.
-
- 17 Otherwise, each value of the base range of the type of the
- discriminant shall be covered [(either explicitly or by others)].
-
- 18 Two distinct discrete_choices of a variant_part shall not cover the same
- value.
-
-
- Static Semantics
- 19 If the component_list of a variant is specified by null, the variant has
- no components.
-
- 20 {govern a variant_part} {govern a variant} The discriminant of a
- variant_part is said to govern the variant_part and its variants. In
- addition, the discriminant of a derived type governs a variant_part and its
- variants if it corresponds (see 3.7) to the discriminant of the variant_part.
-
-
- Dynamic Semantics
-
- 21 A record value contains the values of the components of a particular
- variant only if the value of the discriminant governing the variant is
- covered by the discrete_choice_list of the variant. This rule applies in
- turn to any further variant that is, itself, included in the component_list
- of the given variant.
-
- 22 {elaboration [variant_part]} The elaboration of a variant_part consists
- of the elaboration of the component_list of each variant in the order in
- which they appear.
-
-
- Examples
-
- 23 Example of record type with a variant part:
-
- 24 type Device is (Printer, Disk, Drum);
- type State is (Open, Closed);
-
- 25 type Peripheral(Unit : Device := Disk) is
- record
- Status : State;
- case Unit is
- when Printer =>
- Line_Count : Integer range 1 .. Page_Size;
- when others =>
- Cylinder : Cylinder_Index;
- Track : Track_Number;
- end case;
- end record;
-
- 26 Examples of record subtypes:
-
- 27 subtype Drum_Unit is Peripheral(Drum);
- subtype Disk_Unit is Peripheral(Disk);
-
- 28 Examples of constrained record variables:
-
- 29 Writer : Peripheral(Unit => Printer);
- Archive : Disk_Unit;
-
-
- Extensions to Ada 83
-
- 29.a {extensions to Ada 83} In Ada 83, the discriminant of a
- variant_part is not allowed to be of a generic formal type. This
- restriction is removed in Ada 9X; an others discrete_choice is
- required in this case.
-
- Wording Changes From Ada 83
-
- 29.b The syntactic category choice is removed. The syntax rules
- for variant, array_aggregate, and case_statement now use discrete_
- choice_list or discrete_choice instead. The syntax rule for record_
- aggregate now defines its own syntax for named associations.
-
- 29.c We have added the term Discrete Choice to the title since this
- is where they are talked about. This is analogous to the name of the
- subclause "Index Constraints and Discrete Ranges" in the clause on
- Array Types.
-
- 29.d The rule requiring that the discriminant denote a discriminant
- of the type being defined seems to have been left implicit in RM83.
-
-
-
- 3.9 Tagged Types and Type Extensions
-
- 1 [{dispatching operation [partial]} {polymorphism} {dynamic binding: see
- dispatching operation} {generic unit: see also dispatching operation}
- {variant: see also tagged type} Tagged types and type extensions support
- object-oriented programming, based on inheritance with extension and run-time
- polymorphism via dispatching operations. {object-oriented programming (OOP):
- see tagged types and type extensions} {OOP (object-oriented programming): see
- tagged types and type extensions} {inheritance: see also tagged types and
- type extension}]
-
-
- Language Design Principles
-
- 1.a The intended implementation model is for a tag to be
- represented as a pointer to a statically allocated and link-time
- initialized type descriptor. The type descriptor contains the
- address of the code for each primitive operation of the type. It
- probably also contains other information, such as might make
- membership tests convenient and efficient.
-
- 1.b The primitive operations of a tagged type are known at its
- first freezing point; the type descriptor is laid out at that point.
- It contains linker symbols for each primitive operation; the linker
- fills in the actual addresses.
-
- 1.c Other implementation models are possible.
-
- 1.d The rules ensure that ``dangling dispatching'' is impossible;
- that is, when a dispatching call is made, there is always a body to
- execute. This is different from some other object-oriented
- languages, such as Smalltalk, where it is possible to get a run-time
- error from a missing method.
-
- 1.e Dispatching calls should be efficient, and should have a
- bounded worst-case execution time. This is important in a language
- intended for real-time applications. In the intended implementation
- model, a dispatching call involves calling indirect through the
- appropriate slot in the dispatch table. No complicated "method
- lookup" is involved.
-
- 1.f The programmer should have the choice at each call site of a
- dispatching operation whether to do a dispatching call or a
- statically determined call (i.e. whether the body executed should be
- determined at run time or at compile time).
-
- 1.g The same body should be executed for a call where the tag is
- statically determined to be T'Tag as for a dispatching call where the
- tag is found at run time to be T'Tag. This allows one to test a
- given tagged type with statically determined calls, with some
- confidence that run-time dispatching will produce the same behavior.
-
- 1.h All views of a type should share the same type descriptor and
- the same tag.
-
- 1.i The visibility rules determine what is legal at compile time;
- they have nothing to do with what bodies can be executed at run time.
- Thus, it is possible to dispatch to a subprogram whose declaration is
- not visible at the call site. In fact, this is one of the primary
- facts that gives object-oriented programming its power. The
- subprogram that ends up being dispatched to by a given call might
- even be designed long after the call site has been coded and
- compiled.
-
- 1.j Given that Ada has overloading, determining whether a given
- subprogram overrides another is based both on the names and the type
- profiles of the operations.
-
- 1.k When a type extension is declared, if there is any place within
- its immediate scope where a certain subprogram of the parent is
- visible, then a matching subprogram should override. If there is no
- such place, then a matching subprogram should be totally unrelated,
- and occupy a different slot in the type descriptor. This is
- important to preserve the privacy of private parts; when an operation
- declared in a private part is inherited, the inherited version can be
- overridden only in that private part, in the package body, and in any
- children of the package.
-
- 1.l If an implementation shares code for instances of generic
- bodies, it should be allowed to share type descriptors of tagged
- types declared in the generic body, so long as they are not
- extensions of types declared in the specification of the generic
- unit.
-
- Static Semantics
-
- 2 {tagged type} A record type or private type that has the reserved word
- tagged in its declaration is called a tagged type. [When deriving from a
- tagged type, additional components may be defined. As for any derived type,
- additional primitive subprograms may be defined, and inherited primitive
- subprograms may be overridden.] {type extension} {extension (of a type)} The
- derived type is called an extension of the ancestor type, or simply a type
- extension. {extension (of a record type)} {private extension} {extension (of
- a private type)} Every type extension is also a tagged type, and is either a
- record extension or a private extension of some other tagged type. A record
- extension is defined by a derived_type_definition with a record_extension_
- part. A private extension, which is a partial view of a record extension,
- can be declared in the visible part of a package (see 7.3) or in a generic
- formal part (see 12.5.1).
-
- 2.a Glossary entry: {Tagged type} The objects of a tagged type
- have a run-time type tag, which indicates the specific type with
- which the object was originally created. An operand of a class-wide
- tagged type can be used in a dispatching call; the tag indicates
- which subprogram body to invoke. Nondispatching calls, in which the
- subprogram body to invoke is determined at compile time, are also
- allowed. Tagged types may be extended with additional components.
-
- 2.b Ramification: If a tagged type is declared other than in a
- package_specification, it is impossible to add new primitive
- subprograms for that type, although it can inherit primitive
- subprograms, and those can be overridden. If the user incorrectly
- thinks a certain subprogram is primitive when it is not, and tries to
- call it with a dispatching call, an error message will be given at
- the call site.
-
- 2.c Note that the accessibility rules imply that a tagged type
- declared in a library package_specification cannot be extended in a
- nested subprogram or task body.
-
- 3 {tag of an object} An object of a tagged type has an associated
- (run-time) tag that identifies the specific tagged type used to create the
- object originally. [The tag of an operand of a class-wide tagged type
- T'Class controls which subprogram body is to be executed when a primitive
- subprogram of type T is applied to the operand (see 3.9.2); {dispatching}
- using a tag to control which body to execute is called dispatching.] {type
- tag: see tag} {run-time type: see tag} {type: see also tag} {class: see also
- tag}
-
- 4 The tag of a specific tagged type identifies the full_type_declaration of
- the type. If a declaration for a tagged type occurs within a generic_
- package_declaration, then the corresponding type declarations in distinct
- instances of the generic package are associated with distinct tags. For a
- tagged type that is local to a generic package body, the language does not
- specify whether repeated instantiations of the generic body result in
- distinct tags.
-
- 4.a Reason: This eases generic code sharing.
-
- 4.b Implementation Note: The language does not specify whether
- repeated elaborations of the same full_type_declaration correspond to
- distinct tags. In most cases, we expect that all elaborations will
- correspond to the same tag, since the tag will frequently be the
- address (or index) of a statically allocated type descriptor.
- However, with shared generics, the type descriptor might have to be
- allocated on a per-instance basis, which in some implementation
- models implies per-elaboration of the instantiation.
-
- 5 The following language-defined library package exists:
-
- 6 package Ada.Tags is
- type Tag is private;
-
- 7 function Expanded_Name(T : Tag) return String;
- function External_Tag(T : Tag) return String;
- function Internal_Tag(External : String) return Tag;
-
- 8 Tag_Error : exception;
-
- 9 private
- ... -- not specified by the language
- end Ada.Tags;
-
- 9.a Reason: Tag is a nonlimited, definite subtype, because it
- needs the equality operators, so that tag checking makes sense.
- Also, equality, assignment, and object declaration are all useful
- capabilities for this subtype.
-
- 9.b For an object X and a type T, ``X'Tag = T'Tag'' is not needed,
- because a membership test can be used. However, comparing the tags
- of two objects cannot be done via membership. This is one reason to
- allow equality for type Tag.
-
- 10 The function Expanded_Name returns the full expanded name of the first
- subtype of the specific type identified by the tag, in upper case, starting
- with a root library unit. The result is implementation defined if the type
- is declared within an unnamed block_statement.
-
- 10.a To be honest: This name, as well as each prefix of it, does
- not denote a renaming_declaration.
-
- 10.b Implementation defined: The result of Tags.Expanded_Name for
- types declared within an unnamed block_statement.
-
- 11 The function External_Tag returns a string to be used in an external
- representation for the given tag. The call External_Tag(S'Tag) is equivalent
- to the attribute_reference S'External_Tag (see 13.3).
-
- 11.a Reason: It might seem redundant to provide both the function
- External_Tag and the attribute External_Tag. The function is needed
- because the attribute can't be applied to values of type Tag. The
- attribute is needed so that it can be specifiable via an attribute_
- definition_clause.
-
- 12 The function Internal_Tag returns the tag that corresponds to the given
- external tag, or raises Tag_Error if the given string is not the external tag
- for any specific type of the partition.
-
- 13 For every subtype S of a tagged type T (specific or class-wide), the
- following attributes are defined:
-
- 14 S'Class
- S'Class denotes a subtype of the class-wide type (called
- T'Class in this International Standard) for the class rooted
- at T (or if S already denotes a class-wide subtype, then
- S'Class is the same as S).
-
- 15 {unconstrained (subtype)} {constrained (subtype)}
- S'Class is unconstrained. However, if S is constrained, then
- the values of S'Class are only those that when converted to
- the type T belong to S.
-
- 15.a Ramification: This attribute is defined for both specific and
- class-wide subtypes. The definition is such that S'Class'Class is
- the same as S'Class.
-
- 15.b Note that if S is constrained, S'Class is only partially constrained,
- since there might be additional discriminants added in descendants of
- T which are not constrained.
-
- 15.c Reason: The Class attribute is not defined for untagged subtypes
- (except for incomplete types and private types whose full view is
- tagged -- see 3.10.1 and 7.3.1) so as to preclude implicit conversion
- in the absence of run-time type information. If it were defined for
- untagged subtypes, it would correspond to the concept of universal
- types provided for the predefined numeric classes.
-
- 16 S'Tag
- S'Tag denotes the tag of the type T (or if T is class-wide,
- the tag of the root type of the corresponding class). The
- value of this attribute is of type Tag.
-
- 16.a Reason: S'Class'Tag equals S'Tag, to avoid generic contract model
- problems when S'Class is the actual type associated with a generic
- formal derived type.
-
- 17 Given a prefix X that is of a class-wide tagged type [(after any
- implicit dereference)], the following attribute is defined:
-
- 18 X'Tag
- X'Tag denotes the tag of X. The value of this attribute is of
- type Tag.
-
- 18.a Reason: X'Tag is not defined if X is of a specific type. This is
- primarily to avoid confusion that might result about whether the Tag
- attribute should reflect the tag of the type of X, or the tag of
- X. No such confusion is possible if X is of a class-wide type.
-
-
- Dynamic Semantics
-
- 19 The tag associated with an object of a tagged type is determined as
- follows:
-
- 20 {tag of an object [stand-alone object, component, or aggregate]}
- The tag of a stand-alone object, a component, or an aggregate of
- a specific tagged type T identifies T.
-
- 20.a Discussion: The tag of a formal parameter of type T is not
- necessarily the tag of T, if, for example, the actual was a type
- conversion.
-
- 21 {tag of an object [object created by an allocator]} The tag of an
- object created by an allocator for an access type with a specific
- designated tagged type T, identifies T.
-
- 21.a Discussion: The tag of an object designated by a value of such
- an access type might not be T, if, for example, the access value
- is the result of a type conversion.
-
- 22 {tag of an object [class-wide object]} The tag of an object of a
- class-wide tagged type is that of its initialization expression.
-
- 22.a Ramification: The tag of an object (even a class-wide one)
- cannot be changed after it is initialized, since a
- ``class-wide'' assignment_statement raises Constraint_Error if
- the tags don't match, and a ``specific'' assignment_statement
- does not affect the tag.
-
- 23 {tag of an object [returned by a function]} The tag of the result
- returned by a function whose result type is a specific tagged
- type T identifies T.
-
- 23.a Implementation Note: This requires a run-time check for limited
- tagged types, since they are returned "by-reference." For a
- nonlimited type, a new anonymous object with the appropriate tag
- is created as part of the function return, and then assigned the
- value of the return expression. See 6.5, ``Return Statements''.
-
- 24 {tag of an object [returned by a function]} The tag of the result
- returned by a function with a class-wide result type is that of
- the return expression.
-
- 25 {tag of an object [preserved by type conversion and parameter passing]}
- The tag is preserved by type conversion and by parameter passing. The tag of
- a value is the tag of the associated object (see 6.2). {94-4774.a}
- {94-4842.a}
-
-
- Implementation Permissions
-
- 26 The implementation of the functions in Ada.Tags may raise Tag_Error if
- no specific type corresponding to the tag passed as a parameter exists in the
- partition at the time the function is called.
-
- 26.a Reason: In most implementations, repeated elaborations of the
- same type_declaration will all produce the same tag. In such an
- implementation, Tag_Error will be raised in cases where the internal
- or external tag was passed from a different partition. However, some
- implementations might create a new tag value at run time for each
- elaboration of a type_declaration. In that case, Tag_Error could
- also be raised if the created type no longer exists because the
- subprogram containing it has returned, for example. We don't require
- the latter behavior; hence the word ``may'' in this rule.
-
-
- NOTES
- 27 (62) A type declared with the reserved word tagged should normally be
- declared in a package_specification, so that new primitive subprograms
- can be declared for it.
-
- 28 (63) Once an object has been created, its tag never changes.
-
- 29 (64) Class-wide types are defined to have unknown discriminants (see
- 3.7). This means that objects of a class-wide type have to be
- explicitly initialized (whether created by an object_declaration or an
- allocator), and that aggregates have to be explicitly qualified with a
- specific type when their expected type is class-wide.
-
- 30 (65) If S denotes an untagged private type whose full type is tagged,
- then S'Class is also allowed before the full type definition, but only
- in the private part of the package in which the type is declared (see
- 7.3.1). Similarly, the Class attribute is defined for incomplete types
- whose full type is tagged, but only within the library unit in which the
- incomplete type is declared (see 3.10.1).
-
-
- Examples
-
- 31 Examples of tagged record types:
-
- 32 type Point is tagged
- record
- X, Y : Real := 0.0;
- end record;
-
- 33 type Expression is tagged null record;
- -- Components will be added by each extension
-
-
- Extensions to Ada 83
-
- 33.a {extensions to Ada 83} Tagged types are a new concept.
-
-
-
- 3.9.1 Type Extensions
-
- 1 [{type extension} {extension (of a type)} {record extension} {extension
- (of a record type)} {private extension} {extension (of a private type)} Every
- type extension is a tagged type, and is either a record extension or a
- private extension of some other tagged type.]
-
-
- Language Design Principles
-
- 1.a We want to make sure that we can extend a generic formal tagged
- type, without knowing its discriminants.
-
- 1.b We don't want to allow components in an extension aggregate to
- depend on discriminants inherited from the parent value, since such
- dependence requires staticness in aggregates, at least for variants.
-
- Syntax
-
- 2 record_extension_part ::= with record_definition
-
-
- Legality Rules
-
- 3 The parent type of a record extension shall not be a class-wide type. If
- the parent type is nonlimited, then each of the components of the record_
- extension_part shall be nonlimited. {accessibility rule [record extension]}
- The accessibility level (see 3.10.2) of a record extension shall not be
- statically deeper than that of its parent type. {94-4715.a} {generic
- contract issue [partial]} In addition to the places where Legality Rules
- normally apply (see 12.3), these rules apply also in the private part of an
- instance of a generic unit.
-
- 3.a Reason: If the parent is a limited formal type, then the
- actual might be nonlimited.
-
- 3.b A similar accessibility rule is not needed for private
- extensions, because in a package, the rule will apply to the full_
- type_declaration, and for a generic formal private extension, the
- actual is all that matters.
-
- 4 A type extension shall not be declared in a generic body if the parent
- type is declared outside that body.
-
- 4.a Reason: This paragraph ensures that a dispatching call will
- never attempt to execute an inaccessible subprogram body.
-
- 4.b The part about generic bodies is necessary in order to preserve
- the contract model.
-
- 4.c Since a generic unit can be instantiated at a deeper
- accessibility level than the generic unit, it is necessary to prevent
- type extensions whose parent is declared outside the generic unit.
- The same is true if the parent is a formal of the generic unit. If
- the parent is declared in the generic_declaration (but is not a
- formal), we don't run afoul of the accessibility rules, because we
- know that the instance declaration and body will be at the same
- accessibility level. However, we still have a problem in that case,
- because it might have an unknown number of abstract subprograms, as
- in the following example:
-
- 4.d package P is
- type T is tagged null record;
- function F return T; -- Inherited versions will be abstract.
- end P;
-
- 4.e generic
- type TT is tagged private;
- package Gp is
- type NT is abstract new TT with null record;
- procedure Q(X : in NT) is abstract;
- end Gp;
-
- 4.f package body Gp is
- type NT2 is new NT with null record; -- Illegal!
- procedure Q(X : in NT2) is begin null; end Q;
- -- Is this legal or not? Can't decide because
- -- we don't know whether TT had any functions that go abstract
- -- on extension.
- end Gp;
-
- 4.g package I is new Gp(TT => P.T);
-
- 4.h I.NT is an abstract type with two abstract subprograms: F
- (inherited as abstract) and Q (explicitly declared as abstract). But
- the generic body doesn't know about F, so we don't know that it needs
- to be overridden to make a nonabstract extension of NT. Furthermore,
- a formal tagged limited private type can be extended with limited
- components, but the actual might not be limited, which would allow
- assignment of limited types, which is bad. Hence, we have to
- disallow this case as well.
-
- 4.i If TT were declared as abstract, then we could have the same
- problem with abstract procedures.
-
- 4.j We considered disallowing all tagged types in a generic body,
- for simplicity. We decided not to go that far, in order to avoid
- unnecessary restrictions.
-
- 4.k {accessibility rule [not part of generic contract]} We also
- considered trying make the accessibility level part of the contract;
- i.e. invent some way of saying (in the generic_declaration) ``all
- instances of this generic unit will have the same accessibility level
- as the generic_declaration.'' Unfortunately, that doesn't solve the
- part of the problem having to do with abstract types.
-
- 4.l Children of generic units obviate the need for extension in the
- body somewhat.
-
-
- Dynamic Semantics
-
- 5 {elaboration [record_extension_part]} The elaboration of a record_
- extension_part consists of the elaboration of the record_definition.
-
-
- NOTES
- 6 (66) The term ``type extension'' refers to a type as a whole. The term
- ``extension part'' refers to the piece of text that defines the
- additional components (if any) the type extension has relative to its
- specified ancestor type.
-
- 6.a Discussion: We considered other terminology, such as ``extended
- type.'' However, the terms ``private extended type'' and ``record
- extended type'' did not convey the proper meaning. Hence, we have
- chosen to uniformly use the term ``extension'' as the type resulting
- from extending a type, with ``private extension'' being one produced
- by privately extending the type, and ``record extension'' being one
- produced by extending the type with an additional record-like set of
- components. Note also that the term ``type extension'' refers to the
- result of extending a type in the language Oberon as well (though
- there the term ``extended type'' is also used, interchangeably,
- perhaps because Oberon doesn't have the concept of a ``private
- extension'').
-
- 7 (67) The accessibility rules imply that a tagged type declared in a
- library package_specification can be extended only at library level or
- as a generic formal. When the extension is declared immediately within
- a package_body, primitive subprograms are inherited and are overridable,
- but new primitive subprograms cannot be added.
-
- 8 (68) A name that denotes a component (including a discriminant) of the
- parent type is not allowed within the record_extension_part. Similarly,
- a name that denotes a component defined within the record_extension_part
- is not allowed within the record_extension_part. It is permissible to
- use a name that denotes a discriminant of the record extension,
- providing there is a new known_discriminant_part in the enclosing type
- declaration. (The full rule is given in 3.8.)
-
- 8.a Reason: The restriction against depending on discriminants of the
- parent is to simplify the definition of extension aggregates. The
- restriction against using parent components in other ways is
- methodological; it presumably simplifies implementation as well.
-
- 9 (69) Each visible component of a record extension has to have a unique
- name, whether the component is (visibly) inherited from the parent type
- or declared in the record_extension_part (see 8.3).
-
-
- Examples
-
- 10 Examples of record extensions (of types defined above in 3.9):
- {94-4514.a}
-
- 11 type Painted_Point is new Point with
- record
- Paint : Color := White;
- end record;
- -- Components X and Y are inherited
-
- 12 Origin : constant Painted_Point := (X | Y => 0.0, Paint => Black);
-
- 13 type Literal is new Expression with
- record -- a leaf in an Expression tree
- Value : Real;
- end record;
-
- 14 type Expr_Ptr is access all Expression'Class;
- -- see 3.10
-
- 15 type Binary_Operation is new Expression with
- record -- an internal node in an Expression tree
- Left, Right : Expr_Ptr;
- end record;
-
- 16 type Addition is new Binary_Operation with null record;
- type Subtraction is new Binary_Operation with null record;
- -- No additional components needed for these extensions
-
- 17 Tree : Expr_Ptr := -- A tree representation of ``5.0 + (13.0-7.0)''
- new Addition'(
- Left => new Literal'(Value => 5.0),
- Right => new Subtraction'(
- Left => new Literal'(Value => 13.0),
- Right => new Literal'(Value => 7.0)));
-
-
- Extensions to Ada 83
-
- 17.a {extensions to Ada 83} Type extension is a new concept.
-
-
-
- 3.9.2 Dispatching Operations of Tagged Types
-
- 1 {dispatching operation [distributed]} {dispatching call (on a dispatching
- operation)} {nondispatching call (on a dispatching operation)} {statically
- determined tag} {dynamically determined tag} {polymorphism} {run-time
- polymorphism} {controlling tag (for a call on a dispatching operation)} The
- primitive subprograms of a tagged type are called dispatching operations. [A
- dispatching operation can be called using a statically determined controlling
- tag, in which case the body to be executed is determined at compile time.
- Alternatively, the controlling tag can be dynamically determined, in which
- case the call dispatches to a body that is determined at run time;] such a
- call is termed a dispatching call. [As explained below, the properties of
- the operands and the context of a particular call on a dispatching operation
- determine how the controlling tag is determined, and hence whether or not the
- call is a dispatching call. Run-time polymorphism is achieved when a
- dispatching operation is called by a dispatching call.] {object-oriented
- programming (OOP): see dispatching operations of tagged types} {OOP
- (object-oriented programming): see dispatching operations of tagged types}
- {message: see dispatching call} {method: see dispatching subprogram} {virtual
- function: see dispatching subprogram}
-
-
- Language Design Principles
-
- 1.a The controlling tag determination rules are analogous to the
- overload resolution rules, except they deal with run-time type
- identification (tags) rather than compile-time type resolution. As
- with overload resolution, controlling tag determination may depend on
- operands or result context.
-
- Static Semantics
-
- 2 {call on a dispatching operation} {dispatching operation} A call on a
- dispatching operation is a call whose name or prefix denotes the declaration
- of a primitive subprogram of a tagged type, that is, a dispatching operation.
-
- 2.a Ramification: This definition implies that a call through the
- dereference of an access-to-subprogram value is never considered a
- call on a dispatching operation. Note also that if the prefix
- denotes a renaming_declaration, the place where the renaming occurs
- determines whether it is primitive; the thing being renamed is
- irrelevant.
-
- {controlling operand} A controlling operand in a call on a dispatching
- operation of a tagged type T is one whose corresponding formal parameter is
- of type T or is of an anonymous access type with designated type T;
- {controlling formal parameter} the corresponding formal parameter is called a
- controlling formal parameter. If the controlling formal parameter is an
- access parameter, the controlling operand is the object designated by the
- actual parameter, rather than the actual parameter itself. {controlling
- result} If the call is to a (primitive) function with result type T, then the
- call has a controlling result -- the context of the call can control the
- dispatching.
-
- 3 A name or expression of a tagged type is either statically tagged,
- dynamically tagged, or tag indeterminate, according to whether, when used as
- a controlling operand, the tag that controls dispatching is determined
- statically by the operand's (specific) type, dynamically by its tag at run
- time, or from context. A qualified_expression or parenthesized expression is
- statically, dynamically, or indeterminately tagged according to its operand.
- For other kinds of names and expressions, this is determined as follows:
-
- 4 {statically tagged} The name or expression is statically tagged
- if it is of a specific tagged type and, if it is a call with a
- controlling result, it has at least one statically tagged
- controlling operand;
-
- 4.a Discussion: It is illegal to have both statically tagged and
- dynamically tagged controlling operands in the same call -- see
- below.
-
- 5 {dynamically tagged} The name or expression is dynamically tagged
- if it is of a class-wide type, or it is a call with a controlling
- result and at least one dynamically tagged controlling operand;
-
- 6 {tag indeterminate} The name or expression is tag indeterminate
- if it is a call with a controlling result, all of whose
- controlling operands (if any) are tag indeterminate.
-
- 7 [A type_conversion is statically or dynamically tagged according to
- whether the type determined by the subtype_mark is specific or class-wide,
- respectively.] For a controlling operand that is designated by an actual
- parameter, the controlling operand is statically or dynamically tagged
- according to whether the designated type of the actual parameter is specific
- or class-wide, respectively.
-
- 7.a Ramification: A type_conversion is never tag indeterminate,
- even if its operand is. A designated object is never tag
- indeterminate.
-
-
- Legality Rules
-
- 8 A call on a dispatching operation shall not have both dynamically tagged
- and statically tagged controlling operands.
-
- 8.a Reason: This restriction is intended to minimize confusion
- between whether the dynamically tagged operands are implicitly
- converted to, or tag checked against the specific type of the
- statically tagged operand(s).
-
- 9 If the expected type for an expression or name is some specific tagged
- type, then the expression or name shall not be dynamically tagged unless it
- is a controlling operand in a call on a dispatching operation. Similarly, if
- the expected type for an expression is an anonymous access-to-specific tagged
- type, then the expression shall not be of an access-to-class-wide type unless
- it designates a controlling operand in a call on a dispatching operation.
-
- 9.a Reason: This prevents implicit "truncation" of a
- dynamically-tagged value to the specific type of the target
- object/formal. An explicit conversion is required to request this
- truncation.
-
- 9.b Ramification: This rule applies to all expressions or names
- with a specific expected type, not just those that are actual
- parameters to a dispatching call. This rule does not apply to a
- membership test whose expression is class-wide, since any type that
- covers the tested type is explicitly allowed. See 4.5.2.
-
- 10 In the declaration of a dispatching operation of a tagged type,
- everywhere a subtype of the tagged type appears as a subtype of the profile
- (see 6.1), it shall statically match the first subtype of the tagged type.
- {statically matching [required]} If the dispatching operation overrides an
- inherited subprogram, it shall be subtype conformant with the inherited
- subprogram. {subtype conformance (required)} A dispatching operation shall
- not be of convention Intrinsic. {94-4774.b} If a dispatching operation
- overrides the predefined equals operator, then it shall be of convention Ada
- [(either explicitly or by default -- see 6.3.1)].
-
- 10.a Reason: These rules ensure that constraint checks can be
- performed by the caller in a dispatching call, and parameter passing
- conventions match up properly. A special rule on aggregates prevents
- values of a tagged type from being created that are outside of its
- first subtype.
-
- 11 The default_expression for a controlling formal parameter of a
- dispatching operation shall be tag indeterminate. A controlling formal
- parameter that is an access parameter shall not have a default_expression.
-
- 11.a Reason: The first part ensures that the default_expression
- always produces the "correct" tag when called with or without
- dispatching, or when inherited by a descendant. If it were
- statically tagged, the default would be useless for a dispatching
- call; if it were dynamically tagged, the default would be useless for
- a nondispatching call.
-
- 11.b The second part is consistent with the first part, since
- designated objects are never tag-indeterminate.
-
- 12 A given subprogram shall not be a dispatching operation of two or more
- distinct tagged types.
-
- 12.a Reason: This restriction minimizes confusion since multiple
- dispatching is not provided. The normal solution is to replace all
- but one of the tagged types with their class-wide types.
-
- 13 The explicit declaration of a primitive subprogram of a tagged type
- shall occur before the type is frozen (see 13.14). [For example, new
- dispatching operations cannot be added after objects or values of the type
- exist, nor after deriving a record extension from it, nor after a body.]
-
- 13.a Change: Rule moved here from 13.14, ``Freezing Rules'', as
- per WG9 resolution.
- 13.b Reason: This rule is needed because (1) we don't want people
- dispatching to things that haven't been declared yet, and (2) we want
- to allow tagged type descriptors to be static (allocated statically,
- and initialized to link-time-known symbols). Suppose T2 inherits
- primitive P from T1, and then overrides P. Suppose P is called before
- the declaration of the overriding P. What should it dispatch to? If
- the answer is the new P, we've violated the first principle above.
- If the answer is the old P, we've violated the second principle. (A
- call to the new one necessarily raises Program_Error, but that's
- beside the point.)
-
- 13.c Note that a call upon a dispatching operation of type T will
- freeze T.
-
- 13.d We considered applying this rule to all derived types, for
- uniformity. However, that would be upward incompatible, so we
- rejected the idea. As in Ada 83, for an untagged type, the above
- call upon P will call the old P (which is arguably confusing).
-
- 13.e Implementation Note: Because of this rule, the type
- descriptor can be created (presumably containing linker symbols
- pointing at the not-yet-compiled bodies) at the first freezing point
- of the type. It also prevents, for a tagged type declared in a
- package_specification, overriding in the body or by a child
- subprogram.
-
- 13.f Ramification: A consequence is that for a derived_type_
- declaration in a declarative_part, only the first primitive
- subprogram can be declared by a subprogram_body.
-
-
- Dynamic Semantics
-
- 14 {execution [call on a dispatching operation]} {controlling tag value}
- For the execution of a call on a dispatching operation of a type T, the
- controlling tag value determines which subprogram body is executed. The
- controlling tag value is defined as follows:
-
- 15 {statically determined tag [partial]} If one or more controlling
- operands are statically tagged, then the controlling tag value is
- statically determined to be the tag of T.
-
- 16 If one or more controlling operands are dynamically tagged, then
- the controlling tag value is not statically determined, but is
- rather determined by the tags of the controlling operands. {Tag_
- Check [partial]} {check, language-defined (Tag_Check)} If there
- is more than one dynamically tagged controlling operand, a check
- is made that they all have the same tag. {Constraint_Error
- (raised by failure of run-time check)} If this check fails,
- Constraint_Error is raised unless the call is a function_call
- whose name denotes the declaration of an equality operator
- (predefined or user defined) that returns Boolean, in which case
- the result of the call is defined to indicate inequality, and no
- subprogram_body is executed. This check is performed prior to
- evaluating any tag-indeterminate controlling operands.
-
- 16.a Reason: Tag mismatch is considered an error (except for "=" and
- "/=") since the corresponding primitive subprograms in each
- specific type expect all controlling operands to be of the same
- type. For tag mismatch with an equality operator, rather than
- raising an exception, "=" returns False and "/=" returns True.
- No equality operator is actually invoked, since there is no
- common tag value to control the dispatch. Equality is a special
- case to be consistent with the existing Ada 83 principle that
- equality comparisons, even between objects with different
- constraints, never raise Constraint_Error.
-
- 17 If all of the controlling operands are tag-indeterminate, then:
-
- 18 If the call has a controlling result and is itself a
- (possibly parenthesized or qualified) controlling operand
- of an enclosing call on a dispatching operation of type T,
- then its controlling tag value is determined by the
- controlling tag value of this enclosing call;
-
- 19 {statically determined tag [partial]} Otherwise, the
- controlling tag value is statically determined to be the
- tag of type T.
-
- 19.a Ramification: This includes the cases of a tag-indeterminate
- procedure call, and a tag-indeterminate function_call that is
- used to initialize a class-wide formal parameter or class-wide
- object.
-
- 20 For the execution of a call on a dispatching operation, the body
- executed is the one for the corresponding primitive subprogram of the
- specific type identified by the controlling tag value. The body for an
- explicitly declared dispatching operation is the corresponding explicit body
- for the subprogram. The body for an implicitly declared dispatching
- operation that is overridden is the body for the overriding subprogram, [even
- if the overriding occurs in a private part.] The body for an inherited
- dispatching operation that is not overridden is the body of the corresponding
- subprogram of the parent or ancestor type.
-
- 20.a To be honest: In the unusual case in which a dispatching
- subprogram is explicitly declared (overridden) by a body (with no
- preceding subprogram_declaration), the body for that dispatching
- subprogram is that body; that is, the ``corresponding explicit body''
- in the above rule is the body itself.
-
- 20.b Reason: The wording of the above rule is intended to ensure
- that the same body is executed for a given tag, whether that tag is
- determined statically or dynamically. For a type declared in a
- package, it doesn't matter whether a given subprogram is overridden
- in the visible part or the private part, and it doesn't matter
- whether the call is inside or outside the package. {94-5001.b} For
- example:
-
- 20.c package P1 is
- type T1 is tagged null record;
- procedure Op_A(Arg : in T1);
- procedure Op_B(Arg : in T1);
- end P1;
-
- 20.d with P1; use P1;
- package P2 is
- type T2 is new T1 with null record;
- procedure Op_A(Param : in T2);
- private
- procedure Op_B(Param : in T2);
- end P2;
-
- 20.e with P1; with P2;
- procedure Main is
- X : T2;
- Y : T1'Class := X;
- begin
- P2.Op_A(Param => X); -- Nondispatching call.
- P1.Op_A(Arg => Y); -- Dispatching call.
- P2.Op_B(Arg => X); -- Nondispatching call.
- P1.Op_B(Arg => Y); -- Dispatching call.
- end Main;
-
- 20.f The two calls to Op_A both execute the body of Op_A that has
- to occur in the body of package P2. Similarly, the two calls to Op_B
- both execute the body of Op_B that has to occur in the body of
- package P2, even though Op_B is overridden in the private part of P2.
- Note, however, that the formal parameter names are different for
- P2.Op_A versus P2.Op_B. The overriding declaration for P2.Op_B is
- not visible in Main, so the name in the call actually denotes the
- implicit declaration of Op_B inherited from T1.
-
- 20.g If a call occurs in the program text before an overriding,
- which can happen only if the call is part of a default expression,
- the overriding will still take effect for that call. {94-4457.a}
- {94-4814.a}
-
- 20.h Implementation Note: Even when a tag is not statically
- determined, a compiler might still be able to figure it out and
- thereby avoid the overhead of run-time dispatching.
-
-
- NOTES
- 21 (70) The body to be executed for a call on a dispatching operation is
- determined by the tag; it does not matter whether that tag is determined
- statically or dynamically, and it does not matter whether the
- subprogram's declaration is visible at the place of the call.
- {94-4457.a} {94-4814.a}
-
- 22 (71) This subclause covers calls on primitive subprograms of a tagged
- type. Rules for tagged type membership tests are described in 4.5.2.
- Controlling tag determination for an assignment_statement is described
- in 5.2.
-
- 23 (72) A dispatching call can dispatch to a body whose declaration is not
- visible at the place of the call.
-
- 24 (73) A call through an access-to-subprogram value is never a dispatching
- call, even if the access value designates a dispatching operation.
- Similarly a call whose prefix denotes a subprogram_renaming_declaration
- cannot be a dispatching call unless the renaming itself is the
- declaration of a primitive subprogram.
-
-
- Extensions to Ada 83
-
- 24.a {extensions to Ada 83} The concept of dispatching operations
- is new.
-
-
-
- 3.9.3 Abstract Types and Subprograms
-
- 1 [{abstract type} {abstract data type (ADT): see also abstract type} {ADT
- (abstract data type): see also abstract type} {concrete type: see nonabstract
- type} An abstract type is a tagged type intended for use as a parent type for
- type extensions, but which is not allowed to have objects of its own.
- {abstract subprogram} {concrete subprogram: see nonabstract subprogram} An
- abstract subprogram is a subprogram that has no body, but is intended to be
- overridden at some point when inherited. Because objects of an abstract type
- cannot be created, a dispatching call to an abstract subprogram always
- dispatches to some overriding body.]
-
-
- Language Design Principles
-
- 1.a An abstract subprogram has no body, so the rules in this clause
- are designed to ensure (at compile time) that the body will never be
- invoked. We do so primarily by disallowing the creation of values of
- the abstract type. Therefore, since type conversion and parameter
- passing don't change the tag, we know we will never get a class-wide
- value with a tag identifying an abstract type. This means that we
- only have to disallow nondispatching calls on abstract subprograms
- (dispatching calls will never reach them).
-
- Legality Rules
-
- 2 {abstract type} {type (abstract)} An abstract type is a specific type
- that has the reserved word abstract in its declaration. Only a tagged type
- is allowed to be declared abstract.
-
- 2.a Ramification: Untagged types are never abstract, even though
- they can have primitive abstract subprograms. Such subprograms
- cannot be called, unless they also happen to be dispatching
- operations of some tagged type, and then only via a dispatching call.
-
- 2.b Class-wide types are never abstract. If T is abstract, then it
- is illegal to declare a stand-alone object of type T, but it is OK to
- declare a stand-alone object of type T'Class; the latter will get a
- tag from its initial value, and this tag will necessarily be
- different from T'Tag.
-
- 3 {abstract subprogram} {subprogram (abstract)} A subprogram declared by an
- abstract_subprogram_declaration (see 6.1) is an abstract subprogram. If it
- is a primitive subprogram of a tagged type, then the tagged type shall be
- abstract.
-
- 3.a Ramification: Note that for a private type, this applies to
- both views. The following is illegal:
-
- 3.b package P is
- type T is abstract tagged private;
- function Foo (X : T) return Boolean is abstract; -- Illegal!
- private
- type T is tagged null record; -- Illegal!
- X : T;
- Y : Boolean := Foo (T'Class (X));
- end P;
-
- 3.c The full view of T is not abstract, but has an abstract
- operation Foo, which is illegal. The two lines marked "-- Illegal!"
- are illegal when taken together. {94-4936.a} {94-4949.a}
-
- 3.d Reason: We considered disallowing untagged types from having
- abstract primitive subprograms. However, we rejected that plan,
- because it introduced some silly anomalies, and because such
- subprograms are harmless (if not terribly useful). For example:
-
- 3.e package P is
- type Field_Size is range 0..100;
- type T is abstract tagged null record;
- procedure Print(X : in T; F : in Field_Size := 0) is abstract;
- . . .
- package Q is
- type My_Field_Size is new Field_Size;
- -- implicit declaration of Print(X : T; F : My_Field_Size := 0) \
- is abstract;
- end Q;
-
- 3.f It seemed silly to make the derivative of My_Field_Size
- illegal, just because there was an implicitly declared abstract
- subprogram that was not primitive on some tagged type. Other rules
- could be formulated to solve this problem, but the current ones seem
- like the simplest.
-
- 4 For a derived type, if the parent or ancestor type has an abstract
- primitive subprogram, or a primitive function with a controlling result,
- then:
-
- 5 If the derived type is abstract or untagged, the inherited
- subprogram is abstract.
-
- 5.a Ramification: Note that it is possible to override a concrete
- subprogram with an abstract one.
-
- 6 Otherwise, the subprogram shall be overridden with a nonabstract
- subprogram; [for a type declared in the visible part of a
- package, the overriding may be either in the visible or the
- private part.] However, if the type is a generic formal type,
- the subprogram need not be overridden for the formal type itself;
- [a nonabstract version will necessarily be provided by the actual
- type.] {94-4833.a} {94-4834.a}
-
- 6.a Reason: A function that returns the parent type becomes
- abstract for an abstract type extension (if not overridden)
- because conversion from a parent type to a type extension is not
- defined, and function return semantics is defined in terms of
- conversion. (Note that parameters of mode in out or out do not
- have this problem, because the tag of the actual is not
- changed.)
-
- 6.b Note that the overriding required above can be in the private
- part, which allows the following:
-
- 6.c package Pack1 is
- type Ancestor is abstract ...;
- procedure Do_Something(X : in Ancestor) is abstract;
- end Pack1;
-
- 6.d with Pack1; use Pack1;
- package Pack2 is
- type T1 is new Ancestor with record ...;
- -- A concrete type.
- procedure Do_Something(X : in T1); -- Have to override.
- end Pack2;
-
- 6.e with Pack1; use Pack1;
- with Pack2; use Pack2;
- package Pack3 is
- type T2 is new Ancestor with private;
- -- A concrete type.
- private
- type T2 is new T1 with -- Parent different from ancestor.
- record ... end record;
- -- Here, we inherit Pack2.Do_Something.
- end Pack3;
-
- 6.f T2 inherits an abstract Do_Something, but T is not abstract, so
- Do_Something has to be overridden. However, it is OK to
- override it in the private part. In this case, we override it
- by inheriting a concrete version from a different type.
- Nondispatching calls to Pack3.Do_Something are allowed both
- inside and outside package Pack3.
-
- 7 A call on an abstract subprogram shall be a dispatching call;
- [nondispatching calls to an abstract subprogram are not allowed.]
-
- 7.a Ramification: If an abstract subprogram is not a dispatching
- operation of some tagged type, then it cannot be called at all.
-
- 8 The type of an aggregate, or of an object created by an object_
- declaration or an allocator, or a generic formal object of mode in, shall not
- be abstract. The type of the target of an assignment operation (see 5.2)
- shall not be abstract. The type of a component shall not be abstract. If
- the result type of a function is abstract, then the function shall be
- abstract.
-
- 8.a Reason: This ensures that values of an abstract type cannot be
- created, which ensures that a dispatching call to an abstract
- subprogram will not try to execute the nonexistent body.
-
- 8.b Generic formal objects of mode in are like constants; therefore
- they should be forbidden for abstract types. Generic formal objects
- of mode in out are like renamings; therefore, abstract types are OK
- for them, though probably not terribly useful.
-
- 9 If a partial view is not abstract, the corresponding full view shall not
- be abstract. If a generic formal type is abstract, then for each primitive
- subprogram of the formal that is not abstract, the corresponding primitive
- subprogram of the actual shall not be abstract.
-
- 9.a Discussion: By contrast, we allow the actual type to be
- nonabstract even if the formal type is declared abstract. Hence, the
- most general formal tagged type possible is "type T(<>) is abstract
- tagged limited private;".
-
- 9.b For an abstract private extension declared in the visible part
- of a package, it is only possible for the full type to be nonabstract
- if the private extension has no abstract dispatching operations.
-
- 10 For an abstract type declared in a visible part, an abstract primitive
- subprogram shall not be declared in the private part, unless it is overriding
- an abstract subprogram implicitly declared in the visible part. For a tagged
- type declared in a visible part, a primitive function with a controlling
- result shall not be declared in the private part, unless it is overriding a
- function implicitly declared in the visible part.
-
- 10.a Reason: The ``visible part'' could be that of a package or a
- generic package. This rule is needed because a non-abstract type
- extension declared outside the package would not know about any
- abstract primitive subprograms or primitive functions with
- controlling results declared in the private part, and wouldn't know
- that they need to be overridden with non-abstract subprograms. The
- rule applies to a tagged record type or record extension declared in
- a visible part, just as to a tagged private type or private
- extension. The rule applies to explicitly and implicitly declared
- abstract subprograms:
-
- 10.b package Pack is
- type T is abstract new T1 with private;
- private
- type T is abstract new T2 with record ... end record;
- ...
- end Pack;
-
- 10.c The above example would be illegal if T1 has a non-abstract
- primitive procedure P, but T2 overrides P with an abstract one; the
- private part should override P with a non-abstract version. On the
- other hand, if the P were abstract for both T1 and T2, the example
- would be legal as is.
-
- 11 A generic actual subprogram shall not be an abstract subprogram. The
- prefix of an attribute_reference for the Access, Unchecked_Access, or Address
- attributes shall not denote an abstract subprogram.
-
- 11.a Ramification: An abstract_subprogram_declaration is not
- syntactically a subprogram_declaration. Nonetheless, an abstract
- subprogram is a subprogram, and an abstract_subprogram_declaration is
- a declaration of a subprogram.
-
- 11.b The part about generic actual subprograms includes those given
- by default.
-
-
- NOTES
- 12 (74) Abstractness is not inherited; to declare an abstract type, the
- reserved word abstract has to be used in the declaration of the type
- extension.
-
- 12.a Ramification: A derived type can be abstract even if its parent is
- not. Similarly, an inherited concrete subprogram can be overridden
- with an abstract subprogram.
-
- 13 (75) A class-wide type is never abstract. Even if a class is rooted at
- an abstract type, the class-wide type for the class is not abstract, and
- an object of the class-wide type can be created; the tag of such an
- object will identify some nonabstract type in the class.
-
-
- Examples
-
- 14 Example of an abstract type representing a set of natural numbers:
-
- 15 package Sets is
- subtype Element_Type is Natural;
- type Set is abstract tagged null record;
- function Empty return Set is abstract;
- function Union(Left, Right : Set) return Set is abstract;
- function Intersection(Left, Right : Set) return Set is abstract;
- function Unit_Set(Element : Element_Type) return Set is abstract;
- procedure Take(Element : out Element_Type; From : in out Set) is abstra\
- ct;
- end Sets;
-
-
- NOTES
- 16 (76) Notes on the example: Given the above abstract type, one could
- then derive various (nonabstract) extensions of the type, representing
- alternative implementations of a set. One might use a bit vector, but
- impose an upper bound on the largest element representable, while
- another might use a hash table, trading off space for flexibility.
-
- 16.a Discussion: One way to export a type from a package with some
- components visible and some components private is as follows:
-
- 16.b package P is
- type Public_Part is abstract tagged
- record
- ...
- end record;
- type T is new Public_Part with private;
- ...
- private
- type T is new Public_Part with
- record
- ...
- end record;
- end P;
-
- 16.c The fact that Public_Part is abstract tells clients they have to
- create objects of type T instead of Public_Part. Note that the
- public part has to come first; it would be illegal to declare a
- private type Private_Part, and then a record extension T of it,
- unless T were in the private part after the full declaration of
- Private_Part, but then clients of the package would not have
- visibility to T.
-
-
-
- 3.10 Access Types
-
- 1 {access type} {access value} {designate} A value of an access type (an
- access value) provides indirect access to the object or subprogram it
- designates. Depending on its type, an access value can designate either
- subprograms, objects created by allocators (see 4.8), or more generally
- aliased objects of an appropriate type. {pointer: see access value} {pointer
- type: see access type}
-
- 1.a Discussion: A name denotes an entity; an access value
- designates an entity. The ``dereference'' of an access value X,
- written ``X.all'', is a name that denotes the entity designated by X.
-
-
- Language Design Principles
-
- 1.b Access values should always be well defined (barring uses of
- certain unchecked features of Section 13). In particular,
- uninitialized access variables should be prevented by compile-time
- rules.
-
- Syntax
-
- 2 access_type_definition ::=
- access_to_object_definition
- | access_to_subprogram_definition
-
- 3 access_to_object_definition ::=
- access [general_access_modifier] subtype_indication
-
- 4 general_access_modifier ::= all | constant
-
- 5 access_to_subprogram_definition ::=
- access [protected] procedure parameter_profile
- | access [protected] function parameter_and_result_profile
-
- 6 access_definition ::= access subtype_mark
-
-
- Static Semantics
-
- 7 {access-to-object type} {access-to-subprogram type} {pool-specific access
- type} {general access type} There are two kinds of access types,
- access-to-object types, whose values designate objects, and
- access-to-subprogram types, whose values designate subprograms. {storage
- pool} Associated with an access-to-object type is a storage pool; several
- access types may share the same storage pool. {pool element} A storage pool
- is an area of storage used to hold dynamically allocated objects (called pool
- elements) created by allocators[; storage pools are described further in
- 13.11, ``Storage Management''].
-
- 8 {pool-specific access type} {general access type} Access-to-object types
- are further subdivided into pool-specific access types, whose values can
- designate only the elements of their associated storage pool, and general
- access types, whose values can designate the elements of any storage pool, as
- well as aliased objects created by declarations rather than allocators, and
- aliased subcomponents of other objects.
-
- 8.a Implementation Note: The value of an access type will
- typically be a machine address. However, a value of a pool-specific
- access type can be represented as an offset (or index) relative to
- its storage pool, since it can point only to the elements of that
- pool.
-
- 9 {aliased} A view of an object is defined to be aliased if it is defined
- by an object_declaration or component_definition with the reserved word
- aliased, or by a renaming of an aliased view. In addition, the dereference
- of an access-to-object value denotes an aliased view, as does a view
- conversion (see 4.6) of an aliased view. Finally, the current instance of a
- limited type, and a formal parameter or generic formal object of a tagged
- type are defined to be aliased. {94-4978.a} [Aliased views are the ones that
- can be designated by an access value.] {constrained (object)} {unconstrained
- (object)} {constrained by its initial value} If the view defined by an
- object_declaration is aliased, and the type of the object has discriminants,
- then the object is constrained; if its nominal subtype is unconstrained, then
- the object is constrained by its initial value. [Similarly, if the object
- created by an allocator has discriminants, the object is constrained, either
- by the designated subtype, or by its initial value.] {94-4858.a}
-
- 9.a Glossary entry: {Aliased} An aliased view of an object is one
- that can be designated by an access value. Objects allocated by
- allocators are aliased. Objects can also be explicitly declared as
- aliased with the reserved word aliased. The Access attribute can be
- used to create an access value designating an aliased object.
-
- 9.b Ramification: The current instance of a nonlimited type is not
- aliased.
-
- 9.c The object created by an allocator is aliased, but not its
- subcomponents, except of course for those that themselves have
- aliased in their component_definition.
-
- 9.d The renaming of an aliased object is aliased.
-
- 9.e Slices are never aliased. See 4.1.2 for more discussion.
-
- 9.f Reason: The current instance of a limited type is defined to
- be aliased so that an access discriminant of a component can be
- initialized with T'Access inside the definition of T.
-
- 9.g A formal parameter of a tagged type is defined to be aliased so
- that a (tagged) parameter X may be passed to an access parameter P by
- using P => X'Access. Access parameters are most important for tagged
- types because of dispatching-on-access-parameters (see 3.9.2). By
- restricting this to formal parameters, we minimize problems
- associated with allowing components that are not declared aliased to
- be pointed-to from within the same record.
-
- 9.h A view conversion of an aliased view is aliased so that the
- type of an access parameter can be changed without first converting
- to a named access type. For example:
-
- 9.i type T1 is tagged ...;
- procedure P(X : access T1);
-
- 9.j type T2 is new T1 with ...;
- procedure P(X : access T2) is
- begin
- P(T1(X.all)'Access); -- hand off to T1's P
- . . . -- now do extra T2-specific processing
- end P;
-
- 9.k The rule about objects with discriminants is necessary because
- values of a constrained access subtype can designate an object whose
- nominal subtype is unconstrained; without this rule, a check on every
- use of such values would be required to ensure that the discriminants
- of the object had not changed. With this rule (among others), we
- ensure that if there might exist aliased views of a discriminated
- object, then the object is necessarily constrained. Note that this
- rule is necessary only for untagged types, since a discriminant of a
- tagged type can't have a default, so all tagged discriminated objects
- are always constrained anyway.
-
- 9.l We considered making more kinds of objects aliased by default.
- In particular, any object of a by-reference type will pretty much
- have to be allocated at an addressable location, so it can be passed
- by reference without using bit-field pointers. Therefore, one might
- wish to allow the Access and and Unchecked_Access attributes for such
- objects. However, private parts are transparent to the definition of
- ``by-reference type'', so if we made all objects of a by-reference
- type aliased, we would be violating the privacy of private parts.
- Instead, we would have to define a concept of ``visibly
- by-reference'' and base the rule on that. This seemed to complicate
- the rules more than it was worth, especially since there is no way to
- declare an untagged limited private type to be by-reference, since
- the full type might by nonlimited.
-
- 9.m Discussion: Note that we do not use the term ``aliased'' to
- refer to formal parameters that are referenced through multiple
- access paths (see 6.2).
-
- 10 An access_to_object_definition defines an access-to-object type and its
- first subtype; {designated subtype (of a named access type)} {designated type
- (of a named access type)} the subtype_indication defines the designated
- subtype of the access type. If a general_access_modifier appears, then the
- access type is a general access type. {access-to-constant type} If the
- modifier is the reserved word constant, then the type is an
- access-to-constant type[; a designated object cannot be updated through a
- value of such a type]. {access-to-variable type} If the modifier is the
- reserved word all, then the type is an access-to-variable type[; a designated
- object can be both read and updated through a value of such a type]. If no
- general_access_modifier appears in the access_to_object_definition, the
- access type is a pool-specific access-to-variable type.
-
- 10.a To be honest: The type of the designated subtype is called
- the designated type.
-
- 10.b Reason: The modifier all was picked to suggest that values of
- a general access type could point into ``all'' storage pools, as well
- as to objects declared aliased, and that ``all'' access (both read
- and update) to the designated object was provided. We couldn't think
- of any use for pool-specific access-to-constant types, so any access
- type defined with the modifier constant is considered a general
- access type, and can point into any storage pool or at other
- (appropriate) aliased objects.
-
- 10.c Implementation Note: The predefined generic Unchecked_
- Deallocation can be instantiated for any named access-to-variable
- type. There is no (language-defined) support for deallocating
- objects designated by a value of an access-to-constant type. Because
- of this, an allocator for an access-to-constant type can allocate out
- of a storage pool with no support for deallocation. Frequently, the
- allocation can be done at link-time, if the size and initial value
- are known then.
-
- 10.d Discussion: For the purpose of generic formal type matching,
- the relevant subclasses of access types are access-to-subprogram
- types, access-to-constant types, and (named) access-to-variable
- types, with its subclass (named) general access-to-variable types.
- Pool-specific access-to-variable types are not a separately matchable
- subclass of types, since they don't have any ``extra'' operations
- relative to all (named) access-to-variable types.
-
- 11 {access-to-subprogram type} An access_to_subprogram_definition defines
- an access-to-subprogram type and its first subtype; {designated profile (of
- an access-to-subprogram type)} the parameter_profile or parameter_and_result_
- profile defines the designated profile of the access type. {calling
- convention (associated with a designated profile)} There is a calling
- convention associated with the designated profile[; only subprograms with
- this calling convention can be designated by values of the access type.] By
- default, the calling convention is ``protected'' if the reserved word
- protected appears, and ``Ada'' otherwise. [See Annex B for how to override
- this default.]
-
- 11.a Ramification: The calling convention protected is in italics
- to emphasize that it cannot be specified explicitly by the user.
- This is a consequence of it being a reserved word.
-
- 11.b Implementation Note: For an access-to-subprogram type, the
- representation of an access value might include implementation-
- defined information needed to support up-level references -- for
- example, a static link. The accessibility rules (see 3.10.2) ensure
- that in a "global-display-based" implementation model (as opposed to
- a static-link-based model), an access-to-(unprotected)-subprogram
- value need consist only of the address of the subprogram. The global
- display is guaranteed to be properly set up any time the designated
- subprogram is called. Even in a static-link-based model, the only
- time a static link is definitely required is for an
- access-to-subprogram type declared in a scope nested at least two
- levels deep within subprogram or task bodies, since values of such a
- type might designate subprograms nested a smaller number of levels.
- For the normal case of an access-to-subprogram type declared at the
- outermost (library) level, a code address by itself should be
- sufficient to represent the access value in many implementations.
-
- 11.c For access-to-protected-subprogram, the access values will
- necessarily include both an address (or other identification) of the
- code of the subprogram, as well as the address of the associated
- protected object. This could be thought of as a static link, but it
- will be needed even for global-display-based implementation models.
- It corresponds to the value of the ``implicit parameter'' that is
- passed into every call of a protected operation, to identify the
- current instance of the protected type on which they are to operate.
-
- 11.d Any Elaboration_Check is performed when a call is made through
- an access value, rather than when the access value is first "created"
- via a 'Access. For implementation models that normally put that
- check at the call-site, an access value will have to point to a
- separate entry point that does the check. Alternatively, the access
- value could point to a "subprogram descriptor" that consisted of two
- words (or perhaps more), the first being the address of the code, the
- second being the elaboration bit. Or perhaps more efficiently, just
- the address of the code, but using the trick that the descriptor is
- initialized to point to a Raise-Program-Error routine initially, and
- then set to point to the "real" code when the body is elaborated.
-
- 11.e For implementations that share code between generic
- instantiations, the extra level of indirection suggested above to
- support Elaboration_Checks could also be used to provide a pointer to
- the per-instance data area normally required when calling shared
- code. The trick would be to put a pointer to the per-instance data
- area into the subprogram descriptor, and then make sure that the
- address of the subprogram descriptor is loaded into a "known"
- register whenever an indirect call is performed. Once inside the
- shared code, the address of the per-instance data area can be
- retrieved out of the subprogram descriptor, by indexing off the
- "known" register.
-
- 11.f Essentially the same implementation issues arise for calls on
- dispatching operations of tagged types, except that the static link
- is always known "statically."
-
- 11.g Note that access parameters of an anonymous access-to-
- subprogram type are not permitted. If there were such parameters,
- full ``downward'' closures would be required, meaning that in an
- implementation that uses a per-task (global) display, the display
- would have to be passed as a hidden parameter, and reconstructed at
- the point of call. This was felt to be an undue implementation
- burden, given that an equivalent (actually, more general) capability
- is available via formal subprogram parameters to a generic.
-
- 12 {anonymous access type} {designated subtype (of an anonymous access
- type)} {designated type (of an anonymous access type)} An access_definition
- defines an anonymous general access-to-variable type; the subtype_mark
- denotes its designated subtype. [An access_definition is used in the
- specification of an access discriminant (see 3.7) or an access parameter (see
- 6.1).]
-
- 13 {null value (of an access type)} For each (named) access type, there is
- a literal null which has a null access value designating no entity at all.
- [The null value of a named access type is the default initial value of the
- type.] Other values of an access type are obtained by evaluating an
- attribute_reference for the Access or Unchecked_Access attribute of an
- aliased view of an object or non-intrinsic subprogram, or, in the case of a
- named access-to-object type, an allocator[, which returns an access value
- designating a newly created object (see 3.10.2)].
-
- 13.a Ramification: A value of an anonymous access type (that is,
- the value of an access parameter or access discriminant) cannot be
- null.
-
- 13.b Reason: Access parameters allow dispatching on the tag of the
- object designated by the actual parameter (which gets converted to
- the anonymous access type as part of the call). In order for
- dispatching to work properly, there had better be such an object.
- Hence, the type conversion will raise Constraint_Error if the value
- of the actual parameter is null.
-
- 14 {constrained [subtype]} {unconstrained [subtype]} [All subtypes of an
- access-to-subprogram type are constrained.] The first subtype of a type
- defined by an access_type_definition or an access_to_object_definition is
- unconstrained if the designated subtype is an unconstrained array or
- discriminated type; otherwise it is constrained.
-
- 14.a Proof: The Legality Rules on range_constraints (see 3.5) do
- not permit the subtype_mark of the subtype_indication to denote an
- access-to-scalar type, only a scalar type. The Legality Rules on
- index_constraints (see 3.6.1) and discriminant_constraints (see
- 3.7.1) both permit access-to-composite types in a subtype_indication
- with such _constraints. Note that an access-to-access-to-composite
- is never permitted in a subtype_indication with a constraint.
-
- 14.b Reason: Only composite_constraints are permitted for an
- access type, and only on access-to-composite types. A constraint on
- an access-to-scalar or access-to-access type might be violated due to
- assignments via other access paths that were not so constrained. By
- contrast, if the designated subtype is an array or discriminated
- type, the constraint could not be violated by unconstrained
- assignments, since array objects are always constrained, and aliased
- discriminated objects are also constrained (by fiat, see Static
- Semantics).
-
-
- Dynamic Semantics
-
- 15 {compatibility [composite_constraint with an access subtype]} A
- composite_constraint is compatible with an unconstrained access subtype if it
- is compatible with the designated subtype. {satisfies [for an access value]}
- An access value satisfies a composite_constraint of an access subtype if it
- equals the null value of its type or if it designates an object whose value
- satisfies the constraint.
-
- 16 {elaboration [access_type_definition]} The elaboration of an access_
- type_definition creates the access type and its first subtype. For an
- access-to-object type, this elaboration includes the elaboration of the
- subtype_indication, which creates the designated subtype.
-
- 17 {elaboration [access_definition]} The elaboration of an access_
- definition creates an anonymous general access-to-variable type [(this
- happens as part of the initialization of an access parameter or access
- discriminant)].
-
-
- NOTES
- 18 (77) Access values are called ``pointers'' or ``references'' in some
- other languages.
-
- 19 (78) Each access-to-object type has an associated storage pool; several
- access types can share the same pool. An object can be created in the
- storage pool of an access type by an allocator (see 4.8) for the access
- type. A storage pool (roughly) corresponds to what some other languages
- call a ``heap.'' See 13.11 for a discussion of pools.
-
- 20 (79) Only index_constraints and discriminant_constraints can be applied
- to access types (see 3.6.1 and 3.7.1).
-
-
- Examples
-
- 21 Examples of access-to-object types:
-
- 22 type Peripheral_Ref is access Peripheral; -- see 3.8.1
- type Binop_Ptr is access all Binary_Operation'Class;
- -- general access-to-class-wide,\
- see 3.9.1
-
- 23 Example of an access subtype:
-
- 24 subtype Drum_Ref is Peripheral_Ref(Drum); -- see 3.8.1
-
- 25 Example of an access-to-subprogram type:
-
- 26 type Message_Procedure is access procedure (M : in String := "Error!");
- procedure Default_Message_Procedure(M : in String);
- Give_Message : Message_Procedure := Default_Message_Procedure'Access;
- ...
- procedure Other_Procedure(M : in String);
- ...
- Give_Message := Other_Procedure'Access;
- ...
- Give_Message("File not found."); -- call with parameter (.all is optional)
- Give_Message.all; -- call with no parameters
-
-
- Extensions to Ada 83
-
- 26.a {extensions to Ada 83} The syntax for access_type_definition
- is changed to support general access types (including access-to-
- constants) and access-to-subprograms. The syntax rules for general_
- access_modifier and access_definition are new.
-
- Wording Changes From Ada 83
-
- 26.b We use the term "storage pool" to talk about the data area
- from which allocation takes place. The term "collection" is no
- longer used. ("Collection" and "storage pool" are not the same thing
- because multiple unrelated access types can share the same storage
- pool; see 13.11 for more discussion.)
-
-
-
- 3.10.1 Incomplete Type Declarations
-
- 1 There are no particular limitations on the designated type of an access
- type. In particular, the type of a component of the designated type can be
- another access type, or even the same access type. This permits mutually
- dependent and recursive access types. An incomplete_type_declaration can be
- used to introduce a type to be used as a designated type, while deferring its
- full definition to a subsequent full_type_declaration.
-
-
- Syntax
-
- 2 incomplete_type_declaration ::= type defining_identifier [discriminant_part\
- ];
-
-
- Legality Rules
-
- 3 {requires a completion [incomplete_type_declaration]} An incomplete_type_
- declaration requires a completion, which shall be a full_type_declaration.
- [If the incomplete_type_declaration occurs immediately within either the
- visible part of a package_specification or a declarative_part, then the full_
- type_declaration shall occur later and immediately within this visible part
- or declarative_part. If the incomplete_type_declaration occurs immediately
- within the private part of a given package_specification, then the full_type_
- declaration shall occur later and immediately within either the private part
- itself, or the declarative_part of the corresponding package_body.]
-
- 3.a Proof: This is implied by the next AARM-only rule, plus the
- rules in 3.11.1, ``Completions of Declarations'' which require a
- completion to appear later and immediately within the same
- declarative region.
-
- 3.b To be honest: If the incomplete_type_declaration occurs
- immediately within the visible part of a package_specification, then
- the full_type_declaration shall occur immediately within this visible
- part.
-
- 3.c To be honest: If the implementation supports it, an
- incomplete_type_declaration can be completed by a pragma Import.
-
- 4 If an incomplete_type_declaration has a known_discriminant_part, then a
- full_type_declaration that completes it shall have a fully conforming
- (explicit) known_discriminant_part (see 6.3.1). {full conformance
- (required)} [If an incomplete_type_declaration has no discriminant_part (or
- an unknown_discriminant_part), then a corresponding full_type_declaration is
- nevertheless allowed to have discriminants, either explicitly, or inherited
- via derivation.]
-
- 5 The only allowed uses of a name that denotes an incomplete_type_
- declaration are as follows:
-
- 5.a Discussion: No need to say "prior to the end of the full_type_
- declaration" since the name would not denote the incomplete_type_
- declaration after the end of the full_type_declaration. Also, with
- child library units, it would not be well defined whether they come
- before or after the full_type_declaration for deferred incomplete
- types.
-
- 6 as the subtype_mark in the subtype_indication of an access_to_
- object_definition; [the only form of constraint allowed in this
- subtype_indication is a discriminant_constraint;]
-
- 6.a Implementation Note: We now allow discriminant_constraints even
- if the full type is deferred to the package body. However,
- there is no particular implementation burden because we have
- dropped the concept of the dependent compatibility check. In
- other words, we have effectively repealed AI-00007.
-
- 7 as the subtype_mark defining the subtype of a parameter or result
- of an access_to_subprogram_definition; {94-4618.a}
-
- 7.a Reason: This allows, for example, a record to have a component
- designating a subprogram that takes that same record type as a
- parameter.
-
- 8 as the subtype_mark in an access_definition;
-
- 9 as the prefix of an attribute_reference whose attribute_
- designator is Class; such an attribute_reference is similarly
- restricted to the uses allowed here; when used in this way, the
- corresponding full_type_declaration shall declare a tagged type,
- and the attribute_reference shall occur in the same library unit
- as the incomplete_type_declaration.
-
- 9.a Reason: This is to prevent children from imposing requirements
- on their ancestor library units for deferred incomplete types.
-
- 10 A dereference (whether implicit or explicit -- see 4.1) shall not be of
- an incomplete type.
-
-
- Static Semantics
-
- 11 {incomplete type} An incomplete_type_declaration declares an incomplete
- type and its first subtype; the first subtype is unconstrained if a known_
- discriminant_part appears.
-
- 11.a Reason: If an unknown_discriminant_part or no discriminant_
- part appears, then the constrainedness of the first subtype doesn't
- matter for any other rules or semantics, so we don't bother defining
- it. The case with a known_discriminant_part is the only case in
- which a constraint could later be given in a subtype_indication
- naming the incomplete type.
-
-
- Dynamic Semantics
-
- 12 {elaboration [incomplete_type_declaration]} The elaboration of an
- incomplete_type_declaration has no effect.
-
- 12.a Reason: An incomplete type has no real existence, so it
- doesn't need to be "created" in the usual sense we do for other
- types. It is roughly equivalent to a "forward;" declaration in
- Pascal. Private types are different, because they have a different
- set of characteristics from their full type.
-
-
- NOTES
- 13 (80) {completion legality [partial]} Within a declarative_part, an
- incomplete_type_declaration and a corresponding full_type_declaration
- cannot be separated by an intervening body. This is because a type has
- to be completely defined before it is frozen, and a body freezes all
- types declared prior to it in the same declarative_part (see 13.14).
-
-
- Examples
-
- 14 Example of a recursive type:
-
- 15 type Cell; -- incomplete type declaration
- type Link is access Cell;
- 16 type Cell is
- record
- Value : Integer;
- Succ : Link;
- Pred : Link;
- end record;
-
- 17 Head : Link := new Cell'(0, null, null);
- Next : Link := Head.Succ;
-
- 18 Examples of mutually dependent access types:
-
- 19 type Person(<>); -- incomplete type declaration
- type Car; -- incomplete type declaration
-
- 20 type Person_Name is access Person;
- type Car_Name is access all Car;
-
- 21 type Car is
- record
- Number : Integer;
- Owner : Person_Name;
- end record;
-
- 22 type Person(Sex : Gender) is
- record
- Name : String(1 .. 20);
- Birth : Date;
- Age : Integer range 0 .. 130;
- Vehicle : Car_Name;
- case Sex is
- when M => Wife : Person_Name(Sex => F);
- when F => Husband : Person_Name(Sex => M);
- end case;
- end record;
-
- 23 My_Car, Your_Car, Next_Car : Car_Name := new Car; -- see 4.8
- George : Person_Name := new Person(M);
- ...
- George.Vehicle := Your_Car;
-
-
- Extensions to Ada 83
-
- 23.a {extensions to Ada 83} The full_type_declaration that
- completes an incomplete_type_declaration may have a known_
- discriminant_part even if the incomplete_type_declaration does not.
-
- 23.b A discriminant_constraint may be applied to an incomplete
- type, even if it its completion is deferred to the package body,
- because there is no ``dependent compatibility check'' required any
- more. Of course, the constraint can be specified only if a known_
- discriminant_part was given in the incomplete_type_declaration. As
- mentioned in the previous paragraph, that is no longer required even
- when the full type has discriminants.
-
- Wording Changes From Ada 83
-
- 23.c Dereferences producing incomplete types were not explicitly
- disallowed in RM83, though AI-00039 indicated that it was not
- strictly necessary since troublesome cases would result in
- Constraint_Error at run time, since the access value would
- necessarily be null. However, this introduces an undesirable
- implementation burden, as illustrated by Example 4 of AI-00039:
-
- 23.d package Pack is
- type Pri is private;
- private
- type Sep;
- type Pri is access Sep;
- X : Pri;
- end Pack;
-
- 23.e package body Pack is -- Could be separately compiled!
- type Sep is ...;
- X := new Sep;
- end Pack;
-
- 23.f pragma Elaborate(Pack);
- private package Pack.Child is
- I : Integer := X.all'Size; -- Legal, by AI-00039.
- end Pack.Child;
-
- 23.g Generating code for the above example could be a serious
- implementation burden, since it would require all aliased objects to
- store size dope, and for that dope to be in the same format for all
- kinds of types (or some other equivalently inefficient implemen-
- tation). On the contrary, most implementations allocate dope
- differently (or not at all) for different designated subtypes.
-
-
-
- 3.10.2 Operations of Access Types
-
- 1 [The attribute Access is used to create access values designating aliased
- objects and non-intrinsic subprograms. The ``accessibility'' rules prevent
- dangling references (in the absence of uses of certain unchecked features --
- see Section 13). ]{94-4715.a} {94-4570.a} {94-4724.a} {94-4725.a}
- {94-4780.a}
-
-
- Language Design Principles
-
- 1.a It should be possible for an access value to designate an
- object declared by an object declaration, or a subcomponent thereof.
- In implementation terms, this means pointing at stack-allocated and
- statically allocated data structures. However, dangling references
- should be prevented, primarily via compile-time rules, so long as
- features like Unchecked_Access and Unchecked_Deallocation are not
- used.
-
- 1.b In order to create such access values, we require that the
- access type be a general access type, that the designated object be
- aliased, and that the accessibility rules be obeyed.
-
- Name Resolution Rules
-
- 2 {expected type [access attribute_reference]} For an attribute_reference
- with attribute_designator Access (or Unchecked_Access -- see 13.10), the
- expected type shall be a single access type[; the prefix of such an
- attribute_reference is never interpreted as an implicit_dereference].
- {expected profile [Access attribute_reference prefix]} If the expected type
- is an access-to-subprogram type, then the expected profile of the prefix is
- the designated profile of the access type.
-
- 2.a Discussion: Saying that the expected type shall be a "single
- access type" is our "new" way of saying that the type has to be
- determinable from context using only the fact that it is an access
- type. See 4.2 and 8.6. Specifying the expected profile only implies
- type conformance. The more stringent subtype conformance is required
- by a Legality Rule. This is the only Resolution Rule that applies to
- the name in a prefix of an attribute_reference. In all other cases,
- the name has to be resolved without using context. See 4.1.4.
-
-
- Static Semantics
-
- 3 {accessibility level} {level (accessibility)} {deeper (accessibility
- level)} {depth (accessibility level)} {dangling references (prevention via
- accessibility rules)} {lifetime} [The accessibility rules, which prevent
- dangling references, are written in terms of accessibility levels, which
- reflect the run-time nesting of masters. As explained in 7.6.1, a master is
- the execution of a task_body, a block_statement, a subprogram_body, an entry_
- body, or an accept_statement. An accessibility level is deeper than another
- if it is more deeply nested at run time. {94-4746.} For example, an object
- declared local to a called subprogram has a deeper accessibility level than
- an object declared local to the calling subprogram. The accessibility rules
- for access types require that the accessibility level of an object designated
- by an access value be no deeper than that of the access type. This ensures
- that the object will live at least as long as the access type, which in turn
- ensures that the access value cannot later designate an object that no longer
- exists. The Unchecked_Access attribute may be used to circumvent the
- accessibility rules.]
-
- 4 {statically deeper} {deeper (statically)} [A given accessibility level is
- said to be statically deeper than another if the given level is known at
- compile time (as defined below) to be deeper than the other for all possible
- executions. In most cases, accessibility is enforced at compile time by
- Legality Rules. Run-time accessibility checks are also used, since the
- Legality Rules do not cover certain cases involving access parameters and
- generic packages.] {94-4857.a} {94-4918.a}
-
- 5 Each master, and each entity and view created by it, has an accessibility
- level:
-
- 6 The accessibility level of a given master is deeper than that of
- each dynamically enclosing master, and deeper than that of each
- master upon which the task executing the given master directly
- depends (see 9.3).
-
- 7 An entity or view created by a declaration has the same
- accessibility level as the innermost enclosing master, except in
- the cases of renaming and derived access types described below.
- A parameter of a master has the same accessibility level as the
- master.
-
- 8 The accessibility level of a view of an object or subprogram
- defined by a renaming_declaration is the same as that of the
- renamed view.
-
- 9 The accessibility level of a view conversion is the same as that
- of the operand. {94-4745.a}
-
- 10 For a function whose result type is a return-by-reference type,
- the accessibility level of the result object is the same as that
- of the master that elaborated the function body. For any other
- function, the accessibility level of the result object is that of
- the execution of the called function.
-
- 11 The accessibility level of a derived access type is the same as
- that of its ultimate ancestor.
-
- 12 The accessibility level of the anonymous access type of an access
- discriminant is the same as that of the containing object or
- associated constrained subtype.
-
- 13 The accessibility level of the anonymous access type of an access
- parameter is the same as that of the view designated by the
- actual. If the actual is an allocator, this is the accessibility
- level of the execution of the called subprogram.
-
- 14 The accessibility level of an object created by an allocator is
- the same as that of the access type.
-
- 15 The accessibility level of a view of an object or subprogram
- denoted by a dereference of an access value is the same as that
- of the access type.
-
- 16 The accessibility level of a component, protected subprogram, or
- entry of (a view of) a composite object is the same as that of
- (the view of) the composite object.
-
- 17 {statically deeper} {deeper (statically)} One accessibility level is
- defined to be statically deeper than another in the following cases:
-
- 18 For a master that is statically nested within another master, the
- accessibility level of the inner master is statically deeper than
- that of the outer master.
-
- 18.a To be honest: Strictly speaking, this should talk about the
- constructs (such as subprogram_bodies) being statically nested
- within one another; the masters are really the executions of
- those constructs.
-
- 18.b To be honest: If a given accessibility level is statically
- deeper than another, then each level defined to be the same as
- the given level is statically deeper than each level defined to
- be the same as the other level.
-
- 19 The statically deeper relationship does not apply to the
- accessibility level of the anonymous type of an access parameter;
- that is, such an accessibility level is not considered to be
- statically deeper, nor statically shallower, than any other.
-
- 20 For determining whether one level is statically deeper than
- another when within a generic package body, the generic package
- is presumed to be instantiated at the same level as where it was
- declared; run-time checks are needed in the case of more deeply
- nested instantiations. {94-4857.a} {94-4918.a}
-
- 21 For determining whether one level is statically deeper than
- another when within the declarative region of a type_declaration,
- the current instance of the type is presumed to be an object
- created at a deeper level than that of the type. {94-4857.b}
- {94-4927.a}
-
- 21.a Ramification: In other words, the rules are checked at compile
- time of the type_declaration, in an assume-the-worst manner.
-
- 22 {library level} {level (library)} The accessibility level of all library
- units is called the library level; a library-level declaration or entity is
- one whose accessibility level is the library level.
-
- 22.a Ramification: Library_unit_declarations are library level.
- Nested declarations are library level if they are nested only within
- packages (possibly more than one), and not within subprograms, tasks,
- etc.
-
- 22.b To be honest: The definition of the accessibility level of
- the anonymous type of an access parameter cheats a bit, since it
- refers to the view designated by the actual, but access values
- designate objects, not views of objects. What we really mean is the
- view that ``would be'' denoted by an expression ``X.all'', where X is
- the actual, even though such an expression is a figment of our
- imagination. The definition is intended to be equivalent to the
- following more verbose version: The accessibility level of the
- anonymous type of an access parameter is as follows:
-
- 22.c if the actual is an expression of a named access type --
- the accessibility level of that type;
-
- 22.d if the actual is an allocator -- the accessibility level
- of the execution of the called subprogram;
-
- 22.e if the actual is a reference to the Access attribute --
- the accessibility level of the view denoted by the
- prefix;
-
- 22.f if the actual is a reference to the Unchecked_Access
- attribute -- library accessibility level;
-
- 22.g if the actual is an access parameter -- the accessibility
- level of its type.
-
- 22.h Note that the allocator case is explicitly mentioned in the
- RM9X, because otherwise the definition would be circular: the level
- of the anonymous type is that of the view designated by the actual,
- which is that of the access type.
-
- 22.i Discussion: A deeper accessibility level implies a shorter
- maximum lifetime. Hence, when a rule requires X to have a level that
- is ``not deeper than'' Y's level, this requires that X has a lifetime
- at least as long as Y. (We say ``maximum lifetime'' here, because the
- accessibility level really represents an upper bound on the lifetime;
- an object created by an allocator can have its lifetime prematurely
- ended by an instance of Unchecked_Deallocation.)
-
- 22.j Package elaborations are not masters, and are therefore
- invisible to the accessibility rules: an object declared immediately
- within a package has the same accessibility level as an object
- declared immediately within the declarative region containing the
- package. This is true even in the body of a package; it jibes with
- the fact that objects declared in a package_body live as long as
- objects declared outside the package, even though the body objects
- are not visible outside the package.
-
- 22.k Note that the level of the view denoted by X.all can be
- different from the level of the object denoted by X.all. The former
- is determined by the type of X; the latter is determined either by
- the type of the allocator, or by the master in which the object was
- declared. The former is used in several Legality Rules and run-time
- checks; the latter is used to define when X.all gets finalized. The
- level of a view reflects what we can conservatively ``know'' about
- the object of that view; for example, due to type_conversions, an
- access value might designate an object that was allocated by an
- allocator for a different access type.
-
- 22.l Similarly, the level of the view denoted by X.all.Comp can be
- different from the level of the object denoted by X.all.Comp.
-
- 22.m If Y is statically deeper than X, this implies that Y will be
- (dynamically) deeper than X in all possible executions.
-
- 22.n Most accessibility checking is done at compile time; the rules
- are stated in terms of ``statically deeper than''. The exceptions
- are:
-
- 22.o Checks involving access parameters. The fact that
- ``statically deeper than'' is not defined for the
- anonymous access type of an access parameter implies that
- any rule saying ``shall not be statically deeper than''
- does not apply to such a type, nor to anything defined to
- have ``the same'' level as such a type.
-
- 22.p Checks involving entities and views within generic
- packages. This is because an instantiation can be at a
- level that is more deeply nested than the generic package
- itself. In implementations that use a macro-expansion
- model of generics, these violations can be detected at
- macro-expansion time. For implementations that share
- generics, run-time code is needed to detect the error.
-
- 22.q Checks during function return.
-
- 22.r Note that run-time checks are not required for access
- discriminants, because their accessibility is determined statically
- by the accessibility level of the enclosing object.
-
- 22.s The accessibility level of the result object of a function
- reflects the time when that object will be finalized; we don't allow
- pointers to the object to survive beyond that time. {94-4857.a}
- {94-4918.a}
-
- 22.t We sometimes use the terms ``accessible'' and ``inaccessible''
- to mean that something has an accessibility level that is not deeper,
- or deeper, respectively, than something else.
-
- 22.u Implementation Note: If an accessibility Legality Rule is
- satisfied, then the corresponding run-time check (if any) cannot fail
- (and a reasonable implementation will not generate any checking code)
- unless access parameters or shared generic bodies are involved.
-
- 22.v Accessibility levels are defined in terms of the relations
- ``the same as'' and ``deeper than''. To make the discussion more
- concrete, we can assign actual numbers to each level. Here, we
- assume that library-level accessibility is level 0, and each level
- defined as ``deeper than'' is one level deeper. Thus, a subprogram
- directly called from the environment task (such as the main
- subprogram) would be at level 1, and so on.
-
- 22.w Accessibility is not enforced at compile time for access
- parameters. The ``obvious'' implementation of the run-time checks
- would be inefficient, and would involve distributed overhead;
- therefore, an efficient method is given below. The ``obvious''
- implementation would be to pass the level of the caller at each
- subprogram call, task creation, etc. This level would be incremented
- by 1 for each dynamically nested master. An Accessibility_Check
- would be implemented as a simple comparison -- checking that X is not
- deeper than Y would involve checking that X <= Y.
-
- 22.x A more efficient method is based on passing static nesting
- levels (within constructs that correspond at run time to masters --
- packages don't count). Whenever an access parameter is passed, an
- implicit extra parameter is passed with it. The extra parameter
- represents (in an indirect way) the accessibility level of the
- anonymous access type, and, therefore, the level of the view denoted
- by a dereference of the access parameter. This is analogous to the
- implicit ``Constrained'' bit associated with certain formal
- parameters of an unconstrained but definite composite subtype. In
- this method, we avoid distributed overhead: it is not necessary to
- pass any extra information to subprograms that have no access
- parameters. For anything other than an access parameter and its
- anonymous type, the static nesting level is known at compile time,
- and is defined analogously to the RM9X definition of accessibility
- level (e.g. derived access types get their nesting level from their
- parent). Checking ``not deeper than'' is a "<=" test on the levels.
-
- 22.y For each access parameter, the static depth passed depends on
- the actual, as follows:
- 22.z If the actual is an expression of a named access type,
- pass the static nesting level of that type.
-
- 22.aa If the actual is an allocator, pass the static nesting
- level of the caller, plus one.
-
- 22.bb If the actual is a reference to the Access attribute,
- pass the level of the view denoted by the prefix.
-
- 22.cc If the actual is a reference to the Unchecked_Access
- attribute, pass 0 (the library accessibility level).
-
- 22.dd If the actual is an access parameter, usually just pass
- along the level passed in. However, if the static
- nesting level of the formal (access) parameter is greater
- than the static nesting level of the actual (access)
- parameter, the level to be passed is the minimum of the
- static nesting level of the access parameter and the
- actual level passed in.
-
- 22.ee For the Accessibility_Check associated with a type_conversion
- of an access parameter of a given subprogram to a named access type,
- if the target type is statically nested within the subprogram, do
- nothing; the check can't fail in this case. Otherwise, check that
- the value passed in is <= the static nesting depth of the target
- type. The other Accessibility_Checks are handled in a similar
- manner.
-
- 22.ff This method, using statically known values most of the time,
- is efficient, and, more importantly, avoids distributed overhead.
-
- 22.gg Discussion: Examples of accessibility:
-
- 22.hh package body Lib_Unit is
- type T is tagged ...;
- type A0 is access all T;
- Global: A0 := ...;
- procedure P(X: T) is
- Y: aliased T;
- type A1 is access all T;
- Ptr0: A0 := Global; -- OK.
- Ptr1: A1 := X'Access; -- OK.
- begin
- Ptr1 := Y'Access; -- OK;
- Ptr0 := A0(Ptr1); -- Illegal type conversion!
- Ptr0 := X'Access; -- Illegal reference to Access attribute!
- Ptr0 := Y'Access; -- Illegal reference to Access attribute!
- Global := Ptr0; -- OK.
- end P;
- end Lib_Unit;
-
- 22.ii The above illegal statements are illegal because the
- accessibility level of X and Y are statically deeper than the
- accessibility level of A0. In every possible execution of any
- program including this library unit, if P is called, the
- accessibility level of X will be (dynamically) deeper than that of
- A0. Note that the accessibility levels of X and Y are the same.
-
- 22.jj Here's an example involving access parameters:
-
- 22.kk procedure Main is
- type Level_1_Type is access all Integer;
-
- 22.ll procedure P(X: access Integer) is
- type Nested_Type is access all Integer;
- begin
- ... Nested_Type(X) ... -- (1)
- ... Level_1_Type(X) ... -- (2)
- end P;
-
- 22.mm procedure Q(X: access Integer) is
- procedure Nested(X: access Integer) is
- begin
- P(X);
- end Nested;
- begin
- Nested(X);
- end Q;
-
- 22.nn procedure R is
- Level_2: aliased Integer;
- begin
- Q(Level_2'Access); -- (3)
- end R;
-
- 22.oo Level_1: aliased Integer;
- begin
- Q(Level_1'Access); -- (4)
- R;
- end Main;
-
- 22.pp The run-time Accessibility_Check at (1) can never fail, and
- no code should be generated to check it. The check at (2) will fail
- when called from (3), but not when called from (4).
-
- 22.qq Within a type_declaration, the rules are checked in an
- assume-the-worst manner. For example:
-
- 22.rr package P is
- type Int_Ptr is access all Integer;
- type Rec(D: access Integer) is limited private;
- private
- type Rec_Ptr is access all Rec;
- function F(X: Rec_Ptr) return Boolean;
- function G(X: access Rec) return Boolean;
- type Rec(D: access Integer) is
- record
- C1: Int_Ptr := Int_Ptr(D); -- Illegal!
- C2: Rec_Ptr := Rec'Access; -- Illegal!
- C3: Boolean := F(Rec'Access); -- Illegal!
- C4: Boolean := G(Rec'Access);
- end record;
- end P;
-
- 22.ss C1, C2, and C3 are all illegal, because one might declare an
- object of type Rec at a more deeply nested place than the declaration
- of the type. C4 is legal, but the accessibility level of the object
- will be passed to function G, and constraint checks within G will
- prevent it from doing any evil deeds.
-
- 22.tt Note that we cannot defer the checks on C1, C2, and C3 until
- compile-time of the object creation, because that would cause
- violation of the privacy of private parts. Furthermore, the problems
- might occur within a task or protected body, which the compiler can't
- see while compiling an object creation.
-
- 23 The following attribute is defined for a prefix X that denotes an
- aliased view of an object:
-
- 24 X'Access
- X'Access yields an access value that designates the object
- denoted by X. The type of X'Access is an access-to-object
- type, as determined by the expected type. The expected type
- shall be a general access type. {Unchecked_Access attribute:
- see also Access attribute} X shall denote an aliased view of
- an object[, including possibly the current instance (see 8.6)
- of a limited type within its definition, or a formal
- parameter or generic formal object of a tagged type].
- {94-4978.a} The view denoted by the prefix X shall satisfy
- the following additional requirements, presuming the expected
- type for X'Access is the general access type A:
-
- 25 If A is an access-to-variable type, then the view
- shall be a variable; [on the other hand, if A is
- an access-to-constant type, the view may be
- either a constant or a variable.]
-
- 25.a Discussion: The current instance of a limited type is
- considered a variable.
-
- 26 The view shall not be a subcomponent that depends
- on discriminants of a variable whose nominal
- subtype is unconstrained, unless this subtype is
- indefinite, or the variable is aliased.
-
- 26.a Change: Fixed this rule to match the rule for renaming (see 8.5.1,
- ``Object Renaming Declarations'').
-
- 26.b Discussion: This restriction is intended to be similar to the
- restriction on renaming discriminant-dependent subcomponents.
-
- 26.c Reason: This prevents references to subcomponents that might
- disappear or move or change constraints after creating the
- reference.
-
- 26.d Implementation Note: There was some thought to making this
- restriction more stringent, roughly: "X shall not denote a
- subcomponent of a variable with discriminant-dependent
- subcomponents, if the nominal subtype of the variable is an
- unconstrained definite subtype." This was because in some
- implementations, it is not just the discriminant-dependent
- subcomponents that might move as the result of an assignment
- that changed the discriminants of the enclosing object.
- However, it was decided not to make this change because a
- reasonable implementation strategy was identified to avoid such
- problems, as follows:
-
- 26.e Place non-discriminant-dependent components with any
- aliased parts at offsets preceding any discriminant-
- dependent components in a discriminated record type with
- defaulted discriminants.
-
- 26.f Preallocate the maximum space for unconstrained
- discriminated variables with aliased subcomponents,
- rather than allocating the initial size and moving them
- to a larger (heap-resident) place if they grow as the
- result of an assignment.
-
- 26.g Note that for objects of a by-reference type, it is not an error
- for a programmer to take advantage of the fact that such objects
- are passed by reference. Therefore, the above approach is also
- necessary for discriminated record types with components of a
- by-reference type.
-
- 26.h To make the above strategy work, it is important that a
- component of a derived type is defined to be discriminant-
- dependent if it is inherited and the parent subtype constraint
- is defined in terms of a discriminant of the derived type (see
- 3.7).
-
- 27 If the designated type of A is tagged, then the
- type of the view shall be covered by the
- designated type; if A's designated type is not
- tagged, then the type of the view shall be the
- same, and either A's designated subtype shall
- statically match the nominal subtype of the view,
- or the designated subtype shall be discriminated
- and unconstrained; {statically matching
- [required]}
-
- 27.a Implementation Note: This ensures that the dope for an aliased
- array object can always be stored contiguous with it, but need
- not be if its nominal subtype is constrained.
-
- 28 The accessibility level of the view shall not be
- statically deeper than that of the access type A.
- {94-4715.a} In addition to the places where
- Legality Rules normally apply (see 12.3), this
- rule applies also in the private part of an
- instance of a generic unit. {accessibility rule
- [Access attribute]} {generic contract issue
- [partial]}
-
- 28.a Ramification: In an instance body, a run-time check applies.
-
- 28.b If A is an anonymous access type, then the view can never have a
- deeper accessibility level than A, except when X'Access is used
- to initialize an access discriminant of an object created by an
- allocator. The latter case is illegal if the accessibility
- level of X is statically deeper than that of the access type of
- the allocator; a run-time check is needed in the case where the
- initial value comes from an access parameter. {94-4715.a}
-
- 29 {Accessibility_Check [partial]} {check, language-defined
- (Accessibility_Check)} {Program_Error (raised by failure of
- run-time check)} A check is made that the accessibility level
- of X is not deeper than that of the access type A.
- {94-4715.a} If this check fails, Program_Error is raised.
-
- 29.a Ramification: The check is needed for access parameters and
- in instance bodies.
-
- 29.b Implementation Note: This check requires that some indication
- of lifetime is passed as an implicit parameter along with access
- parameters. No such requirement applies to access discriminants,
- since the checks associated with them are all compile-time checks.
-
- 30 {implicit subtype conversion [Access attribute]} If the
- nominal subtype of X does not statically match the designated
- subtype of A, a view conversion of X to the designated
- subtype is evaluated (which might raise Constraint_Error --
- see 4.6) and the value of X'Access designates that view.
-
- 31 The following attribute is defined for a prefix P that denotes a
- subprogram:
-
- 32 P'Access
- P'Access yields an access value that designates the
- subprogram denoted by P. The type of P'Access is an
- access-to-subprogram type (S), as determined by the expected
- type. {accessibility rule [Access attribute]} The
- accessibility level of P shall not be statically deeper than
- that of S. {94-4715.a} {generic contract issue [partial]} In
- addition to the places where Legality Rules normally apply
- (see 12.3), this rule applies also in the private part of an
- instance of a generic unit. The profile of P shall be
- subtype-conformant with the designated profile of S, and
- shall not be Intrinsic. {94-4774.b} {subtype conformance
- (required)} If the subprogram denoted by P is declared within
- a generic body, S shall be declared within the generic body.
- {94-4692.a} {94-4702.a} {94-4706.a} {94-4708.a}
-
- 32.a Discussion: The part about generic bodies is worded in terms of the
- denoted subprogram, not the denoted view; this implies that renaming
- is invisible to this part of the rule. This rule is partly to
- prevent contract model problems with respect to the accessibility
- rules, and partly to ease shared-generic-body implementations, in
- which a subprogram declared in an instance needs to have a different
- calling convention from other subprograms with the same profile.
-
- 32.b Overload resolution ensures only that the profile is type-conformant.
- This rule specifies that subtype conformance is required (which also
- requires matching calling conventions). P cannot denote an entry
- because access-to-subprogram types never have the entry calling
- convention. P cannot denote an enumeration literal or an attribute
- function because these have intrinsic calling conventions.
-
-
- NOTES
- 33 (81) The Unchecked_Access attribute yields the same result as the Access
- attribute for objects, but has fewer restrictions (see 13.10). There
- are other predefined operations that yield access values: an allocator
- can be used to create an object, and return an access value that
- designates it (see 4.8); evaluating the literal null yields a null
- access value that designates no entity at all (see 4.2).
-
- 34 (82) {predefined operations [of an access type]} The predefined
- operations of an access type also include the assignment operation,
- qualification, and membership tests. Explicit conversion is allowed
- between general access types with matching designated subtypes; explicit
- conversion is allowed between access-to-subprogram types with subtype
- conformant profiles (see 4.6). {subtype conformance [partial]} Named
- access types have predefined equality operators; anonymous access types
- do not (see 4.5.2).
-
- 34.a Reason: By not having equality operators for anonymous access
- types, we eliminate the need to specify exactly where the predefined
- operators for anonymous access types would be defined, as well as the
- need for an implementer to insert an implicit declaration for "=",
- etc. at the appropriate place in their symbol table. Note that
- 'Access and ".all" are defined, and ":=" is defined though useless
- since all instances are constant. The literal null is also defined
- for the purposes of overload resolution, but is disallowed by a
- Legality Rule of this subclause.
-
- 35 (83) The object or subprogram designated by an access value can be named
- with a dereference, either an explicit_dereference or an implicit_
- dereference. See 4.1.
-
- 36 (84) A call through the dereference of an access-to-subprogram value is
- never a dispatching call.
-
- 36.a Proof: See 3.9.2.
-
- 37 (85) {downward closure} {closure (downward)} The accessibility rules
- imply that it is not possible to use the Access attribute to implement
- ``downward closures'' -- that is, to pass a more-nested subprogram as a
- parameter to a less-nested subprogram, as might be desired for example
- for an iterator abstraction. Instead, downward closures can be
- implemented using generic formal subprograms (see 12.6). Note that
- Unchecked_Access is not allowed for subprograms.
-
- 38 (86) Note that using an access-to-class-wide tagged type with a
- dispatching operation is a potentially more structured alternative to
- using an access-to-subprogram type.
-
- 39 (87) An implementation may consider two access-to-subprogram values to
- be unequal, even though they designate the same subprogram. This might
- be because one points directly to the subprogram, while the other points
- to a special prologue that performs an Elaboration_Check and then jumps
- to the subprogram. See 4.5.2.
-
- 39.a Ramification: If equality of access-to-subprogram values is
- important to the logic of a program, a reference to the Access
- attribute of a subprogram should be evaluated only once and stored in
- a global constant for subsequent use and equality comparison.
-
-
- Examples
-
- 40 Example of use of the Access attribute:
-
- 41 Martha : Person_Name := new Person(F); -- see 3.10.1
- Cars : array (1..2) of aliased Car;
- ...
- Martha.Vehicle := Cars(1)'Access;
- George.Vehicle := Cars(2)'Access;
-
-
- Extensions to Ada 83
-
- 41.a {extensions to Ada 83} We no longer make things like 'Last and
- ".component" (basic) operations of an access type that need to be
- "declared" somewhere. Instead, implicit dereference in a prefix
- takes care of them all. This means that there should never be a case
- when X.all'Last is legal while X'Last is not. See AI-00154.
-
-
-
- 3.11 Declarative Parts
-
- 1 [A declarative_part contains declarative_items (possibly none).]
-
-
- Syntax
-
- 2 declarative_part ::= {declarative_item}
-
- 3 declarative_item ::=
- basic_declarative_item | body
-
- 4 basic_declarative_item ::=
- basic_declaration | representation_clause | use_clause
-
- 5 body ::= proper_body | body_stub
-
- 6 proper_body ::=
- subprogram_body | package_body | task_body | protected_body
-
-
- Dynamic Semantics
-
- 7 {elaboration [declarative_part]} The elaboration of a declarative_part
- consists of the elaboration of the declarative_items, if any, in the order in
- which they are given in the declarative_part.
-
- 8 {elaborated} An elaborable construct is in the elaborated state after the
- normal completion of its elaboration. Prior to that, it is not yet
- elaborated.
- 8.a Ramification: The elaborated state is only important for
- bodies; certain uses of a body raise an exception if the body is not
- yet elaborated.
-
- 8.b Note that "prior" implies before the start of elaboration, as
- well as during elaboration.
-
- 8.c The use of the term "normal completion" implies that if the
- elaboration propagates an exception or is aborted, the declaration is
- not elaborated. RM83 missed the aborted case.
-
- 9 {Elaboration_Check [partial]} {check, language-defined (Elaboration_
- Check)} For a construct that attempts to use a body, a check (Elaboration_
- Check) is performed, as follows:
-
- 10 For a call to a (non-protected) subprogram that has an explicit
- body, a check is made that the subprogram_body is already
- elaborated. This check and the evaluations of any actual
- parameters of the call are done in an arbitrary order.
-
- 10.a Discussion: AI-00180 specifies that there is no elaboration
- check for a subprogram defined by a pragma Interface (or
- equivalently, pragma Import). AI-00430 specifies that there is
- no elaboration check for an enumeration literal. AI-00406
- specifies that the evaluation of parameters and the elaboration
- check occur in an arbitrary order. AI-00406 applies to generic
- instantiation as well (see below).
-
- 11 For a call to a protected operation of a protected type (that has
- a body -- no check is performed if a pragma Import applies to the
- protected type), a check is made that the protected_body is
- already elaborated. This check and the evaluations of any actual
- parameters of the call are done in an arbitrary order.
-
- 11.a Discussion: A protected type has only one elaboration ``bit,''
- rather than one for each operation, because one call may result
- in evaluating the barriers of other entries, and because there
- are no elaborable declarations between the bodies of the
- operations. In fact, the elaboration of a protected_body does
- not elaborate the enclosed bodies, since they are not considered
- independently elaborable.
-
- 11.b Note that there is no elaboration check when calling a task
- entry. Task entry calls are permitted even before the
- associated task_body has been seen. Such calls are simply
- queued until the task is activated and reaches a corresponding
- accept_statement. We considered a similar rule for protected
- entries -- simply queuing all calls until the protected_body was
- seen, but felt it was not worth the possible implementation
- overhead, particularly given that there might be multiple
- instances of the protected type.
-
- 12 For the activation of a task, a check is made by the activator
- that the task_body is already elaborated. If two or more tasks
- are being activated together (see 9.2), as the result of the
- elaboration of a declarative_part or the initialization for the
- object created by an allocator, this check is done for all of
- them before activating any of them.
-
- 12.a Reason: As specified by AI-00149, the check is done by
- the activator, rather than by the task itself. If it were done
- by the task itself, it would be turned into a Tasking_Error in
- the activator, and the other tasks would still be activated.
-
- 13 For the instantiation of a generic unit that has a body, a check
- is made that this body is already elaborated. This check and the
- evaluation of any explicit_generic_actual_parameters of the
- instantiation are done in an arbitrary order.
-
- 14 {Program_Error (raised by failure of run-time check)} The exception
- Program_Error is raised if any of these checks fails.
-
-
- Extensions to Ada 83
-
- 14.a {extensions to Ada 83} The syntax for declarative_part is
- modified to remove the ordering restrictions of Ada 83; that is, the
- distinction between basic_declarative_items and later_declarative_
- items within declarative_parts is removed. This means that things
- like use_clauses and variable_declarations can be freely intermixed
- with things like bodies.
-
- 14.b The syntax rule for proper_body now allows a protected_body,
- and the rules for elaboration checks now cover calls on protected
- operations.
-
- Wording Changes From Ada 83
-
- 14.c The syntax rule for later_declarative_item is removed; the
- syntax rule for declarative_item is new.
-
- 14.d RM83 defines ``elaborated'' and ``not yet elaborated'' for
- declarative_items here, and for other things in 3.1, ``Declara-
- tions''. That's no longer necessary, since these terms are fully
- defined in 3.1.
-
- 14.e In RM83, all uses of declarative_part are optional (except for
- the one in block_statement with a declare) which is sort of strange,
- since a declarative_part can be empty, according to the syntax. That
- is, declarative_parts are sort of ``doubly optional''. In Ada 9X,
- these declarative_parts are always required (but can still be empty).
- To simplify description, we go further and say (see 5.6, ``Block
- Statements'') that a block_statement without an explicit declarative_
- part is equivalent to one with an empty one.
-
-
-
- 3.11.1 Completions of Declarations
-
- 1 Declarations sometimes come in two parts. {requires a completion} A
- declaration that requires a second part is said to require completion.
- {completion (compile-time concept)} The second part is called the completion
- of the declaration (and of the entity declared), and is either another
- declaration, a body, or a pragma.
-
- 1.a Discussion: Throughout the RM9X, there are rules about
- completions that define the following:
-
- 1.b Which declarations require a corresponding completion.
-
- 1.c Which constructs can only serve as the completion of a
- declaration.
-
- 1.d Where the completion of a declaration is allowed to be.
-
- 1.e What kinds of completions are allowed to correspond to
- each kind of declaration that allows one.
-
- 1.f Don't confuse this compile-time concept with the run-time
- concept of completion defined in 7.6.1.
-
- 1.g Note that the declaration of a private type (if limited) can be
- completed with the declaration of a task type, which is then
- completed with a body. Thus, a declaration can actually come in
- three parts.
-
-
- Name Resolution Rules
-
- 2 A construct that can be a completion is interpreted as the completion of
- a prior declaration only if:
-
- 3 The declaration and the completion occur immediately within the
- same declarative region;
-
- 4 The defining name or defining_program_unit_name in the completion
- is the same as in the declaration, or in the case of a pragma,
- the pragma applies to the declaration;
-
- 5 If the declaration is overloadable, then the completion either
- has a type-conformant profile, or is a pragma. {type conformance
- (required)}
-
-
- Legality Rules
-
- 6 An implicit declaration shall not have a completion. {requires a
- completion [distributed]} For any explicit declaration that is specified to
- require completion, there shall be a corresponding explicit completion.
-
- 6.a Discussion: The implicit declarations of predefined operators
- are not allowed to have a completion. Enumeration literals, although
- they are subprograms, are not allowed to have a corresponding
- subprogram_body. That's because the completion rules are described
- in terms of constructs (subprogram_declarations) and not entities
- (subprograms). When a completion is required, it has to be explicit;
- the implicit null package_body that Section 7 talks about cannot
- serve as the completion of a package_declaration if a completion is
- required.
-
- 7 At most one completion is allowed for a given declaration. Additional
- requirements on completions appear where each kind of completion is defined.
-
- 7.a Ramification: A subunit is not a completion; the stub is.
-
- 7.b If the completion of a declaration is also a declaration, then
- that declaration might have a completion, too. For example, a
- limited private type can be completed with a task type, which can
- then be completed with a task body. This is not a violation of the
- ``at most one completion'' rule.
-
- 8 {completely defined} A type is completely defined at a place that is
- after its full type definition (if it has one) and after all of its
- subcomponent types are completely defined. A type shall be completely
- defined before it is frozen (see 13.14 and 7.3).
-
- 8.a Change: Rule moved here from 13.14, ``Freezing Rules'', as per
- WG9 resolution.
-
- 8.b Reason: Index types are always completely defined -- no need
- to mention them. There is no way for a completely defined type to
- depend on the value of a (still) deferred constant.
-
-
- NOTES
- 9 (88) Completions are in principle allowed for any kind of explicit
- declaration. However, for some kinds of declaration, the only allowed
- completion is a pragma Import, and implementations are not required to
- support pragma Import for every kind of entity.
- 9.a Discussion: In fact, we expect that implementations will not
- support pragma Import of things like types -- it's hard to even
- define the semantics of what it would mean. Therefore, in practice,
- not every explicit declaration can have a completion. In any case,
- if an implementation chooses to support pragma Import for, say,
- types, it can place whatever restrictions on the feature it wants to.
- For example, it might want the pragma to be a freezing point for the
- type.
-
- 10 (89) There are rules that prevent premature uses of declarations that
- have a corresponding completion. The Elaboration_Checks of 3.11 prevent
- such uses at run time for subprograms, protected operations, tasks, and
- generic units. The rules of 13.14, ``Freezing Rules'' prevent, at
- compile time, premature uses of other entities such as private types and
- deferred constants.
-
-
- Wording Changes From Ada 83
-
- 10.a This subclause is new. It is intended to cover all kinds of
- completions of declarations, be they a body for a spec, a full type
- for an incomplete or private type, a full constant declaration for a
- deferred constant declaration, or a pragma Import for any kind of
- entity.
-
-
-
- Section 4: Names and Expressions
-
-
- 1 [The rules applicable to the different forms of name and expression, and
- to their evaluation, are given in this section.]
-
-
-
- 4.1 Names
-
- 1 [Names can denote declared entities, whether declared explicitly or
- implicitly (see 3.1). Names can also denote objects or subprograms
- designated by access values; the results of type_conversions or function_
- calls; subcomponents and slices of objects and values; protected subprograms,
- single entries, entry families, and entries in families of entries. Finally,
- names can denote attributes of any of the foregoing.]
-
-
- Syntax
-
- 2 name ::=
- direct_name | explicit_dereference
- | indexed_component | slice
- | selected_component | attribute_reference
- | type_conversion | function_call
- | character_literal
-
- 3 direct_name ::= identifier | operator_symbol
-
- 3.a Discussion: character_literal is no longer a direct_name.
- character_literals are usable even when the corresponding
- enumeration_type_declaration is not visible. See 4.2.
-
- 4 prefix ::= name | implicit_dereference
-
- 5 explicit_dereference ::= name.all
-
- 6 implicit_dereference ::= name
-
-
- 7 [Certain forms of name (indexed_components, selected_components, slices,
- and attributes) include a prefix that is either itself a name that denotes
- some related entity, or an implicit_dereference of an access value that
- designates some related entity.]
-
-
- Name Resolution Rules
-
- 8 {dereference} {expected type [dereference name]} The name in a
- dereference (either an implicit_dereference or an explicit_dereference) is
- expected to be of any access type.
-
-
- Static Semantics
-
- 9 {nominal subtype [associated with a dereference]} If the type of the name
- in a dereference is some access-to-object type T, then the dereference
- denotes a view of an object, the nominal subtype of the view being the
- designated subtype of T.
-
- 9.a Ramification: If the value of the name is the result of an
- access type conversion, the dereference denotes a view created as
- part of the conversion. The nominal subtype of the view is not
- necessarily the same as that used to create the designated object.
- See 4.6.
-
- 9.b To be honest: {nominal subtype [of a name]} We sometimes refer
- to the nominal subtype of a particular kind of name rather than the
- nominal subtype of the view denoted by the name (presuming the name
- denotes a view of an object). These two uses of nominal subtype are
- intended to mean the same thing.
-
- 10 {profile [associated with a dereference]} If the type of the name in a
- dereference is some access-to-subprogram type S, then the dereference denotes
- a view of a subprogram, the profile of the view being the designated profile
- of S.
-
- 10.a Ramification: This means that the formal parameter names and
- default expressions to be used in a call whose name or prefix is a
- dereference are those of the designated profile, which need not be
- the same as those of the subprogram designated by the access value,
- since 'Access requires only subtype conformance, not full
- conformance.
-
-
- Dynamic Semantics
-
- 11 {evaluation [name]} The evaluation of a name determines the entity
- denoted by the name. This evaluation has no other effect for a name that is
- a direct_name or a character_literal.
-
- 12 {evaluation [name that has a prefix]} [The evaluation of a name that has
- a prefix includes the evaluation of the prefix.] {evaluation [prefix]} The
- evaluation of a prefix consists of the evaluation of the name or the
- implicit_dereference. The prefix denotes the entity denoted by the name or
- the implicit_dereference.
-
- 13 {evaluation [dereference]} The evaluation of a dereference consists of
- the evaluation of the name and the determination of the object or subprogram
- that is designated by the value of the name. {Access_Check [partial]}
- {check, language-defined (Access_Check)} A check is made that the value of
- the name is not the null access value. {Constraint_Error (raised by failure
- of run-time check)} Constraint_Error is raised if this check fails. The
- dereference denotes the object or subprogram designated by the value of the
- name.
-
-
- Examples
-
- 14 Examples of direct names:
-
- 15
- Pi -- the direct name of a number (see 3.3.2)
- Limit -- the direct name of a constant (see 3.3.1)
- Count -- the direct name of a scalar variable (see 3.3.1)
- Board -- the direct name of an array variable (see 3.6.1)
- Matrix -- the direct name of a type (see 3.6)
- Random -- the direct name of a function (see 6.1)
- Error -- the direct name of an exception (see 11.1)
-
- 16 Examples of dereferences:
-
- 17
- Next_Car.all -- explicit dereference denoting the object designate\
- d by
- -- the access variable Next_Car (see 3.10.1)
- Next_Car.Owner -- selected component with implicit dereference;
- -- same as Next_Car.all.Owner
-
-
- Extensions to Ada 83
-
- 17.a {extensions to Ada 83} Type conversions and function calls are
- now considered names that denote the result of the operation. In the
- case of a type conversion used as an actual parameter or that is of a
- tagged type, the type conversion is considered a variable if the
- operand is a variable. This simplifies the description of
- "parameters of the form of a type conversion" as well as better
- supporting an important OOP paradigm that requires the combination of
- a conversion from a class-wide type to some specific type followed
- immediately by component selection. Function calls are considered
- names so that a type conversion of a function call and the function
- call itself are treated equivalently in the grammar. A function call
- is considered the name of a constant, and can be used anywhere such a
- name is permitted. See 6.5.
-
- 17.b Type conversions of a tagged type are permitted anywhere their
- operand is permitted. That is, if the operand is a variable, then
- the type conversion can appear on the left-hand side of an
- assignment_statement. If the operand is an object, then the type
- conversion can appear in an object renaming or as a prefix. See 4.6.
-
- Wording Changes From Ada 83
-
- 17.c Everything of the general syntactic form name(...) is now
- syntactically a name. In any realistic parser, this would be a
- necessity since distinguishing among the various name(...) constructs
- inevitably requires name resolution. In cases where the construct
- yields a value rather than an object, the name denotes the value
- rather than an object. Names already denote values in Ada 83 with
- named numbers, components of the result of a function call, etc.
- This is partly just a wording change, and partly an extension of
- functionality (see Extensions heading above).
-
- 17.d The syntax rule for direct_name is new. It is used in places
- where direct visibility is required. It's kind of like Ada 83's
- simple_name, but simple_name applied to both direct visibility and
- visibility by selection, and furthermore, it didn't work right for
- operator_symbols. The syntax rule for simple_name is removed, since
- its use is covered by a combination of direct_name and selector_name.
- The syntactic categories direct_name and selector_name are similar;
- it's mainly the visibility rules that distinguish the two. The
- introduction of direct_name requires the insertion of one new
- explicit textual rule: to forbid statement_identifiers from being
- operator_symbols. This is the only case where the explicit rule is
- needed, because this is the only case where the declaration of the
- entity is implicit. For example, there is no need to syntactically
- forbid (say) ``X: "Rem";'', because it is impossible to declare a
- type whose name is an operator_symbol in the first place.
-
- 17.e The syntax rules for explicit_dereference and implicit_
- dereference are new; this makes other rules simpler, since
- dereferencing an access value has substantially different semantics
- from selected_components. We also use name instead of prefix in the
- explicit_dereference rule since that seems clearer. Note that these
- rules rely on the fact that function calls are now names, so we don't
- need to use prefix to allow functions calls in front of .all.
-
- 17.f Discussion: Actually, it would be reasonable to allow any
- primary in front of .all, since only the value is needed, but that
- would be a bit radical.
-
- 17.g We no longer use the term appropriate for a type since we now
- describe the semantics of a prefix in terms of implicit dereference.
-
-
-
- 4.1.1 Indexed Components
-
- 1 [An indexed_component denotes either a component of an array or an entry
- in a family of entries. {array indexing: see indexed_component} ]
-
-
- Syntax
-
- 2 indexed_component ::= prefix(expression {, expression})
-
-
- Name Resolution Rules
-
- 3 The prefix of an indexed_component with a given number of expressions
- shall resolve to denote an array (after any implicit dereference) with the
- corresponding number of index positions, or shall resolve to denote an entry
- family of a task or protected object (in which case there shall be only one
- expression).
-
- 4 {expected type [indexed_component expression]} The expected type for each
- expression is the corresponding index type.
-
-
- Static Semantics
-
- 5 When the prefix denotes an array, the indexed_component denotes the
- component of the array with the specified index value(s). {nominal subtype
- [associated with an indexed_component]} The nominal subtype of the indexed_
- component is the component subtype of the array type.
-
- 5.a Ramification: In the case of an array whose components are
- aliased, and of an unconstrained discriminated subtype, the
- components are constrained even though their nominal subtype is
- unconstrained. (This is because all aliased discriminated objects
- are constrained. See 3.10.2.) In all other cases, an array
- component is constrained if and only if its nominal subtype is
- constrained.
-
- 6 When the prefix denotes an entry family, the indexed_component denotes
- the individual entry of the entry family with the specified index value.
-
-
- Dynamic Semantics
-
- 7 {evaluation [indexed_component]} For the evaluation of an indexed_
- component, the prefix and the expressions are evaluated in an arbitrary
- order. The value of each expression is converted to the corresponding index
- type. {implicit subtype conversion [array index]} {Index_Check [partial]}
- {check, language-defined (Index_Check)} A check is made that each index value
- belongs to the corresponding index range of the array or entry family denoted
- by the prefix. {Constraint_Error (raised by failure of run-time check)}
- Constraint_Error is raised if this check fails.
-
-
- Examples
-
- 8 Examples of indexed components:
-
- 9
- My_Schedule(Sat) -- a component of a one-dimensional array (see 3.6.\
- 1)
- Page(10) -- a component of a one-dimensional array (see 3.6)
- Board(M, J + 1) -- a component of a two-dimensional array (see 3.6.\
- 1)
- Page(10)(20) -- a component of a component (see 3.6)
- Request(Medium) -- an entry in a family of entries (see 9.1)
- Next_Frame(L)(M, N) -- a component of a function call (see 6.1)
-
-
- NOTES
- 10 (1) Notes on the examples: Distinct notations are used for components
- of multidimensional arrays (such as Board) and arrays of arrays (such as
- Page). The components of an array of arrays are arrays and can
- therefore be indexed. Thus Page(10)(20) denotes the 20th component of
- Page(10). In the last example Next_Frame(L) is a function call
- returning an access value that designates a two-dimensional array.
-
-
-
- 4.1.2 Slices
-
- 1 [{array slice} A slice denotes a one-dimensional array formed by a
- sequence of consecutive components of a one-dimensional array. A slice of a
- variable is a variable; a slice of a constant is a constant;] a slice of a
- value is a value.
-
-
- Syntax
-
- 2 slice ::= prefix(discrete_range)
-
-
- Name Resolution Rules
-
- 3 The prefix of a slice shall resolve to denote a one-dimensional array
- (after any implicit dereference).
-
- 4 {expected type [slice discrete_range]} The expected type for the
- discrete_range of a slice is the index type of the array type.
-
-
- Static Semantics
-
- 5 A slice denotes a one-dimensional array formed by the sequence of
- consecutive components of the array denoted by the prefix, corresponding to
- the range of values of the index given by the discrete_range.
-
- 6 The type of the slice is that of the prefix. Its bounds are those
- defined by the discrete_range.
-
-
- Dynamic Semantics
-
- 7 {evaluation [slice]} For the evaluation of a slice, the prefix and the
- discrete_range are evaluated in an arbitrary order. {Index_Check [partial]}
- {check, language-defined (Index_Check)} {null slice} If the slice is not a
- null slice (a slice where the discrete_range is a null range), then a check
- is made that the bounds of the discrete_range belong to the index range of
- the array denoted by the prefix. {Constraint_Error (raised by failure of
- run-time check)} Constraint_Error is raised if this check fails.
-
-
- NOTES
- 8 (2) A slice is not permitted as the prefix of an Access attribute_
- reference, even if the components or the array as a whole are aliased.
- See 3.10.2.
-
- 8.a Proof: Slices are not aliased, by 3.10, ``Access Types''.
-
- 8.b Reason: This is to ease implementation of general-access-to-array.
- If slices were aliased, implementations would need to store array
- dope with the access values, which is not always desirable given
- access-to-incomplete types completed in a package body.
-
- 9 (3) For a one-dimensional array A, the slice A(N .. N) denotes an array
- that has only one component; its type is the type of A. On the other
- hand, A(N) denotes a component of the array A and has the corresponding
- component type.
-
-
- Examples
-
- 10 Examples of slices:
-
- 11
- Stars(1 .. 15) -- a slice of 15 characters (see \
- 3.6.3)
- Page(10 .. 10 + Size) -- a slice of 1 + Size components (see \
- 3.6)
- Page(L)(A .. B) -- a slice of the array Page(L) (see \
- 3.6)
- Stars(1 .. 0) -- a null slice (see \
- 3.6.3)
- My_Schedule(Weekday) -- bounds given by subtype (see \
- 3.6.1 and 3.5.1)
- Stars(5 .. 15)(K) -- same as Stars(K) (see \
- 3.6.3)
- -- provided that K is in 5 .. 15
-
-
-
- 4.1.3 Selected Components
-
- 1 [Selected_components are used to denote components (including
- discriminants), entries, entry families, and protected subprograms; they are
- also used as expanded names as described below. {dot selection: see
- selected_component}]
-
-
- Syntax
-
- 2 selected_component ::= prefix . selector_name
-
- 3 selector_name ::= identifier | character_literal | operator_symbol
-
-
- Name Resolution Rules
-
- 4 {expanded name} A selected_component is called an expanded name if,
- according to the visibility rules, at least one possible interpretation of
- its prefix denotes a package or an enclosing named construct (directly, not
- through a subprogram_renaming_declaration or generic_renaming_declaration).
-
- 4.a Discussion: See AI-00187.
-
- 5 A selected_component that is not an expanded name shall resolve to denote
- one of the following:
-
- 5.a Ramification: If the prefix of a selected_component denotes an
- enclosing named construct, then the selected_component is interpreted
- only as an expanded name, even if the named construct is a function
- that could be called without parameters.
-
- 6 A component [(including a discriminant)]:
-
- 7 The prefix shall resolve to denote an object or value of some
- non-array composite type (after any implicit dereference).
- {94-4493.c} The selector_name shall resolve to denote a
- discriminant_specification of the type, or, unless the type is a
- protected type, a component_declaration of the type. The
- selected_component denotes the corresponding component of the
- object or value.
-
- 7.a Reason: The components of a protected object cannot be
- named except by an expanded name, even from within the
- corresponding protected body. The protected body may not
- reference the the private components of some arbitrary object of
- the protected type; the protected body may reference components
- of the current instance only (by an expanded name or a direct_
- name).
-
- 7.b Ramification: Only the discriminants and components
- visible at the place of the selected_component can be selected,
- since a selector_name can only denote declarations that are
- visible (see 8.3).
-
- 8 A single entry, an entry family, or a protected subprogram:
-
- 9 The prefix shall resolve to denote an object or value of some
- task or protected type (after any implicit dereference). The
- selector_name shall resolve to denote an entry_declaration or
- subprogram_declaration occurring (implicitly or explicitly)
- within the visible part of that type. The selected_component
- denotes the corresponding entry, entry family, or protected
- subprogram.
-
- 9.a Reason: This explicitly says ``visible part'' because
- even though the body has visibility on the private part, it
- cannot call the private operations of some arbitrary object of
- the task or protected type, only those of the current instance
- (and expanded name notation has to be used for that).
-
- 10 An expanded name shall resolve to denote a declaration that occurs
- immediately within a named declarative region, as follows:
-
- 11 The prefix shall resolve to denote either a package [(including
- the current instance of a generic package, or a rename of a
- package)], or an enclosing named construct.
-
- 12 The selector_name shall resolve to denote a declaration that
- occurs immediately within the declarative region of the package
- or enclosing construct [(the declaration shall be visible at the
- place of the expanded name -- see 8.3)]. The expanded name
- denotes that declaration.
-
- 12.a Ramification: Hence, a library unit or subunit can use an
- expanded name to refer to the declarations within the private
- part of its parent unit, as well as to other children that have
- been mentioned in with_clauses.
-
- 13 If the prefix does not denote a package, then it shall be a
- direct_name or an expanded name, and it shall resolve to denote a
- program unit (other than a package), the current instance of a
- type, a block_statement, a loop_statement, or an accept_statement
- (in the case of an accept_statement or entry_body, no family
- index is allowed); the expanded name shall occur within the
- declarative region of this construct. Further, if this construct
- is a callable construct and the prefix denotes more than one such
- enclosing callable construct, then the expanded name is
- ambiguous, independently of the selector_name.
-
-
- Dynamic Semantics
-
- 14 {evaluation [selected_component]} The evaluation of a selected_component
- includes the evaluation of the prefix.
-
- 15 {Discriminant_Check [partial]} {check, language-defined (Discriminant_
- Check)} For a selected_component that denotes a component of a variant, a
- check is made that the values of the discriminants are such that the value or
- object denoted by the prefix has this component. {Constraint_Error (raised
- by failure of run-time check)} {Constraint_Error (raised by failure of
- run-time check)} The exception Constraint_Error is raised if this check
- fails.
-
-
- Examples
-
- 16 Examples of selected components:
-
- 17
- Tomorrow.Month -- a record component (se\
- e 3.8)
- Next_Car.Owner -- a record component (se\
- e 3.10.1)
- Next_Car.Owner.Age -- a record component (se\
- e 3.10.1)
- -- the previous two lines involve implicit dereferenc\
- es
- Writer.Unit -- a record component (a discriminant) (se\
- e 3.8.1)
- Min_Cell(H).Value -- a record component of the result (se\
- e 6.1)
- -- of the function call Min_Cell(H)
- Control.Seize -- an entry of a protected object (se\
- e 9.4)
- Pool(K).Write -- an entry of the task Pool(K) (se\
- e 9.4)
-
- 18 Examples of expanded names:
-
- 19
- Key_Manager."<" -- an operator of the visible part of a package (se\
- e 7.3.1)
- Dot_Product.Sum -- a variable declared in a function body (se\
- e 6.1)
- Buffer.Pool -- a variable declared in a protected unit (se\
- e 9.11)
- Buffer.Read -- an entry of a protected unit (se\
- e 9.11)
- Swap.Temp -- a variable declared in a block statement (se\
- e 5.6)
- Standard.Boolean -- the name of a predefined type (se\
- e A.1)
-
-
- Extensions to Ada 83
-
- 19.a {extensions to Ada 83} We now allow an expanded name to use a
- prefix that denotes a rename of a package, even if the selector is
- for an entity local to the body or private part of the package, so
- long as the entity is visible at the place of the reference. This
- eliminates a preexisting anomaly where references in a package body
- may refer to declarations of its visible part but not those of its
- private part or body when the prefix is a rename of the package.
-
- Wording Changes From Ada 83
-
- 19.b The syntax rule for selector_name is new. It is used in
- places where visibility, but not necessarily direct visibility, is
- required. See 4.1, ``Names'' for more information.
-
- 19.c The description of dereferencing an access type has been moved
- to 4.1, ``Names''; name.all is no longer considered a selected_
- component.
-
- 19.d The rules have been restated to be consistent with our new
- terminology, to accommodate class-wide types, etc.
-
-
-
- 4.1.4 Attributes
-
- 1 {attribute} [An attribute is a characteristic of an entity that can be
- queried via an attribute_reference or a range_attribute_reference.]
-
-
- Syntax
-
- 2 attribute_reference ::= prefix'attribute_designator
-
- 3 attribute_designator ::=
- identifier[(static_expression)]
- | Access | Delta | Digits
-
- 4 range_attribute_reference ::= prefix'range_attribute_designator
-
- 5 range_attribute_designator ::= Range[(static_expression)]
-
-
- Name Resolution Rules
-
- 6 In an attribute_reference, if the attribute_designator is for an
- attribute defined for (at least some) objects of an access type, then the
- prefix is never interpreted as an implicit_dereference; otherwise (and for
- all range_attribute_references), if the type of the name within the prefix is
- of an access type, the prefix is interpreted as an implicit_dereference.
- Similarly, if the attribute_designator is for an attribute defined for (at
- least some) functions, then the prefix is never interpreted as a
- parameterless function_call; otherwise (and for all range_attribute_
- references), if the prefix consists of a name that denotes a function, it is
- interpreted as a parameterless function_call.
-
- 6.a Discussion: The first part of this rule is essentially a
- "preference" against implicit dereference, so that it is possible to
- ask for, say, 'Size of an access object, without automatically
- getting the size of the object designated by the access object. This
- rule applies to 'Access, 'Unchecked_Access, 'Size, and 'Address, and
- any other attributes that are defined for at least some access
- objects.
-
- 6.b The second part of this rule implies that, for a parameterless
- function F, F'Address is the address of F, whereas F'Size is the size
- of the anonymous constant returned by F.
-
- 6.c We normally talk in terms of expected type or profile for name
- resolution rules, but we don't do this for attributes because certain
- attributes are legal independent of the type or the profile of the
- prefix.
-
- 7 {expected type [attribute_designator expression]} {expected type [range_
- attribute_designator expression]} The expression, if any, in an attribute_
- designator or range_attribute_designator is expected to be of any integer
- type.
- Legality Rules
-
- 8 The expression, if any, in an attribute_designator or range_attribute_
- designator shall be static.
-
-
- Static Semantics
-
- 9 An attribute_reference denotes a value, an object, a subprogram, or some
- other kind of program entity.
-
- 9.a Ramification: The attributes defined by the language are
- summarized in Annex K. Implementations can define additional
- attributes.
-
- 10 [A range_attribute_reference X'Range(N) is equivalent to the range
- X'First(N) .. X'Last(N), except that the prefix is only evaluated once.
- Similarly, X'Range is equivalent to X'First .. X'Last, except that the prefix
- is only evaluated once.]
-
-
- Dynamic Semantics
-
- 11 {evaluation [attribute_reference]} {evaluation [range_attribute_
- reference]} The evaluation of an attribute_reference (or range_attribute_
- reference) consists of the evaluation of the prefix.
-
-
- Implementation Permissions
-
- 12 An implementation may provide implementation-defined attributes; the
- identifier for an implementation-defined attribute shall differ from those of
- the language-defined attributes.
-
- 12.a Implementation defined: Implementation-defined attributes.
-
- 12.b Ramification: They cannot be reserved words because reserved
- words are not legal identifiers.
-
- 12.c The semantics of implementation-defined attributes, and any
- associated rules, are, of course, implementation defined. For
- example, the implementation defines whether a given implementation-
- defined attribute can be used in a static expression. {94-4539.b}
-
-
- NOTES
- 13 (4) Attributes are defined throughout this International Standard, and
- are summarized in Annex K.
-
- 14 (5) In general, the name in a prefix of an attribute_reference (or a
- range_attribute_reference) has to be resolved without using any context.
- However, in the case of the Access attribute, the expected type for the
- prefix has to be a single access type, and if it is an
- access-to-subprogram type (see 3.10.2) then the resolution of the name
- can use the fact that the profile of the callable entity denoted by the
- prefix has to be type conformant with the designated profile of the
- access type. {type conformance (required)}
-
- 14.a Proof: In the general case, there is no ``expected type'' for the
- prefix of an attribute_reference. In the special case of 'Access,
- there is an ``expected profile'' for the prefix.
-
- 14.b Reason: 'Access is a special case, because without it, it would be
- very difficult to take 'Access of an overloaded subprogram.
-
-
- Examples
-
- 15 Examples of attributes:
-
- 16
- Color'First -- minimum value of the enumeration type Color (see 3.\
- 5.1)
- Rainbow'Base'First -- same as Color'First (see 3.\
- 5.1)
- Real'Digits -- precision of the type Real (see 3.\
- 5.7)
- Board'Last(2) -- upper bound of the second dimension of Board (see 3.\
- 6.1)
- Board'Range(1) -- index range of the first dimension of Board (see 3.\
- 6.1)
- Pool(K)'Terminated -- True if task Pool(K) is terminated (see 9.\
- 1)
- Date'Size -- number of bits for records of type Date (see 3.\
- 8)
- Message'Address -- address of the record variable Message (see 3.\
- 7.1)
-
-
- Extensions to Ada 83
-
- 16.a {extensions to Ada 83} We now uniformly treat X'Range as
- X'First..X'Last, allowing its use with scalar subtypes.
-
- 16.b We allow any integer type in the static_expression of an
- attribute designator, not just a value of universal_integer. The
- preference rules ensure upward compatibility.
-
- Wording Changes From Ada 83
-
- 16.c We use the syntactic category attribute_reference rather than
- simply "attribute" to avoid confusing the name of something with the
- thing itself.
-
- 16.d The syntax rule for attribute_reference now uses identifier
- instead of simple_name, because attribute identifiers are not
- required to follow the normal visibility rules.
-
- 16.e We now separate attribute_reference from range_attribute_
- reference, and enumerate the reserved words that are legal attribute
- or range attribute designators. We do this because identifier no
- longer includes reserved words.
-
- 16.f The Ada 9X name resolution rules are a bit more explicit than
- in Ada 83. The Ada 83 rule said that the "meaning of the prefix of
- an attribute must be determinable independently of the attribute
- designator and independently of the fact that it is the prefix of an
- attribute." That isn't quite right since the meaning even in Ada 83
- embodies whether or not the prefix is interpreted as a parameterless
- function call, and in Ada 9X, it also embodies whether or not the
- prefix is interpreted as an implicit_dereference. So the attribute
- designator does make a difference -- just not much.
-
- 16.g Note however that if the attribute designator is Access, it
- makes a big difference in the interpretation of the prefix (see
- 3.10.2).
-
-
-
- 4.2 Literals
-
- 1 [{literal} A literal represents a value literally, that is, by means of
- notation suited to its kind.] A literal is either a numeric_literal, a
- character_literal, the literal null, or a string_literal. {constant: see
- also literal}
-
- 1.a Discussion: An enumeration literal that is an identifier
- rather than a character_literal is not considered a literal in the
- above sense, because it involves no special notation ``suited to its
- kind.'' It might more properly be called an enumeration_identifier,
- except for historical reasons.
-
-
- Name Resolution Rules
-
- 2 {expected type [null literal]} The expected type for a literal null shall
- be a single access type.
-
- 2.a Discussion: This new wording ("expected type ... shall be a
- single ... type") replaces the old "shall be determinable" stuff. It
- reflects an attempt to simplify and unify the description of the
- rules for resolving aggregates, literals, type conversions, etc. See
- 8.6, ``The Context of Overload Resolution'' for the details.
-
- 3 {expected type [character_literal]} {expected profile [character_
- literal]} For a name that consists of a character_literal, either its
- expected type shall be a single character type, in which case it is
- interpreted as a parameterless function_call that yields the corresponding
- value of the character type, or its expected profile shall correspond to a
- parameterless function with a character result type, in which case it is
- interpreted as the name of the corresponding parameterless function declared
- as part of the character type's definition (see 3.5.1). In either case, the
- character_literal denotes the enumeration_literal_specification.
-
- 3.a Discussion: See 4.1.3 for the resolution rules for a selector_
- name that is a character_literal.
-
- 4 {expected type [string_literal]} The expected type for a primary that is
- a string_literal shall be a single string type.
-
-
- Legality Rules
-
- 5 A character_literal that is a name shall correspond to a defining_
- character_literal of the expected type, or of the result type of the expected
- profile.
-
- 6 For each character of a string_literal with a given expected string type,
- there shall be a corresponding defining_character_literal of the component
- type of the expected string type.
-
- 7 A literal null shall not be of an anonymous access type[, since such
- types do not have a null value (see 3.10)].
-
- 7.a Reason: This is a legality rule rather than an overloading
- rule, to simplify implementations.
-
-
- Static Semantics
-
- 8 An integer literal is of type universal_integer. A real literal is of
- type universal_real.
-
-
- Dynamic Semantics
-
- 9 {evaluation [numeric literal]} {evaluation [null literal]} {null access
- value} {null pointer: see null access value} The evaluation of a numeric
- literal, or the literal null, yields the represented value.
-
- 10 {evaluation [string_literal]} The evaluation of a string_literal that is
- a primary yields an array value containing the value of each character of the
- sequence of characters of the string_literal, as defined in 2.6. The bounds
- of this array value are determined according to the rules for positional_
- array_aggregates (see 4.3.3), except that for a null string literal, the
- upper bound is the predecessor of the lower bound.
-
- 11 {Range_Check [partial]} {check, language-defined (Range_Check)} For the
- evaluation of a string_literal of type T, a check is made that the value of
- each character of the string_literal belongs to the component subtype of T.
- For the evaluation of a null string literal, a check is made that its lower
- bound is greater than the lower bound of the base range of the index type.
- {Constraint_Error (raised by failure of run-time check)} The exception
- Constraint_Error is raised if either of these checks fails.
-
- 11.a Ramification: The checks on the characters need not involve
- more than two checks altogether, since one need only check the
- characters of the string with the lowest and highest position numbers
- against the range of the component subtype.
-
-
- NOTES
- 12 (6) Enumeration literals that are identifiers rather than character_
- literals follow the normal rules for identifiers when used in a name
- (see 4.1 and 4.1.3). Character_literals used as selector_names follow
- the normal rules for expanded names (see 4.1.3).
-
-
- Examples
-
- 13 Examples of literals:
-
- 14
- 3.14159_26536 -- a real literal
- 1_345 -- an integer literal
- 'A' -- a character literal
- "Some Text" -- a string literal
-
-
- Incompatibilities With Ada 83
-
- 14.a {incompatibilities with Ada 83} Because character_literals are
- now treated like other literals, in that they are resolved using
- context rather than depending on direct visibility, additional
- qualification might be necessary when passing a character_literal to
- an overloaded subprogram.
-
- Extensions to Ada 83
-
- 14.b {extensions to Ada 83} Character_literals are now treated
- analogously to null and string_literals, in that they are resolved
- using context, rather than their content; the declaration of the
- corresponding defining_character_literal need not be directly
- visible.
-
- Wording Changes From Ada 83
-
- 14.c Name Resolution rules for enumeration literals that are not
- character_literals are not included anymore, since they are neither
- syntactically nor semantically "literals" but are rather names of
- parameterless functions.
-
-
-
- 4.3 Aggregates
-
- 1 [{aggregate} An aggregate combines component values into a composite
- value of an array type, record type, or record extension.] {literal: see
- also aggregate}
-
-
- Syntax
-
- 2 aggregate ::= record_aggregate | extension_aggregate | array_aggregate
-
-
- Name Resolution Rules
-
- 3 {expected type [aggregate]} The expected type for an aggregate shall be a
- single nonlimited array type, record type, or record extension.
-
- 3.a Discussion: See 8.6, ``The Context of Overload Resolution''
- for the meaning of ``shall be a single ... type.''
-
-
- Legality Rules
-
- 4 An aggregate shall not be of a class-wide type.
-
- 4.a Ramification: When the expected type in some context is
- class-wide, an aggregate has to be explicitly qualified by the
- specific type of value to be created, so that the expected type for
- the aggregate itself is specific.
-
- 4.b Discussion: We used to disallow aggregates of a type with
- unknown discriminants. However, that was unnecessarily restrictive
- in the case of an extension aggregate, and irrelevant to a record
- aggregate (since a type that is legal for a record aggregate could
- not possibly have unknown discriminants) and to an array aggregate
- (the only specific types that can have unknown discriminants are
- private types, private extensions, and types derived from them).
-
-
- Dynamic Semantics
-
- 5 {evaluation [aggregate]} For the evaluation of an aggregate, an anonymous
- object is created and values for the components or ancestor part are obtained
- (as described in the subsequent subclause for each kind of the aggregate) and
- assigned into the corresponding components or ancestor part of the anonymous
- object. {assignment operation (during evaluation of an aggregate)} Obtaining
- the values and the assignments occur in an arbitrary order. The value of the
- aggregate is the value of this object.
-
- 5.a Discussion: The ancestor part is the set of components
- inherited from the ancestor type. The syntactic category ancestor_
- part is the expression or subtype_mark that specifies how the
- ancestor part of the anonymous object should be initialized.
-
- 5.b Ramification: The assignment operations do the necessary value
- adjustment, as described in 7.6. Note that the value as a whole is
- not adjusted -- just the subcomponents (and ancestor part, if any).
- 7.6 also describes when this anonymous object is finalized.
-
- 5.c If the ancestor_part is a subtype_mark the Initialize procedure
- for the ancestor type is applied to the ancestor part after
- default-initializing it, unless the procedure is abstract, as
- described in 7.6. The Adjust procedure for the ancestor type is not
- called in this case, since there is no assignment to the ancestor
- part as a whole.
-
- 6 {Discriminant_Check [partial]} {check, language-defined (Discriminant_
- Check)} If an aggregate is of a tagged type, a check is made that its value
- belongs to the first subtype of the type. {Constraint_Error (raised by
- failure of run-time check)} Constraint_Error is raised if this check fails.
-
- 6.a Ramification: This check ensures that no values of a tagged
- type are ever outside the first subtype, as required for inherited
- dispatching operations to work properly (see 3.4). This check will
- always succeed if the first subtype is unconstrained. This check is
- not extended to untagged types to preserve upward compatibility.
-
-
- Extensions to Ada 83
-
- 6.b {extensions to Ada 83} We now allow extension_aggregates.
-
- Wording Changes From Ada 83
-
- 6.c We have adopted new wording for expressing the rule that the
- type of an aggregate shall be determinable from the outside, though
- using the fact that it is nonlimited record (extension) or array.
-
- 6.d An aggregate now creates an anonymous object. This is
- necessary so that controlled types will work (see 7.6).
-
-
-
- 4.3.1 Record Aggregates
-
- 1 [In a record_aggregate, a value is specified for each component of the
- record or record extension value, using either a named or a positional
- association.]
-
-
- Syntax
-
- 2 record_aggregate ::= (record_component_association_list)
-
- 3 record_component_association_list ::=
- record_component_association {, record_component_association}
- | null record
-
- 4 record_component_association ::=
- [ component_choice_list => ] expression
-
- 5 component_choice_list ::=
- component_selector_name {| component_selector_name}
- | others
-
- 6 {named component association} A record_component_association is a
- named component association if it has a component_choice_list;
- {positional component association} otherwise, it is a positional
- component association. Any positional component associations shall
- precede any named component associations. If there is a named
- association with a component_choice_list of others, it shall come last.
-
- 6.a Discussion: These rules were implied by the BNF in an early
- version of the RM9X, but it made the grammar harder to read, and was
- inconsistent with how we handle discriminant constraints. Note that
- for array aggregates we still express some of the rules in the
- grammar, but array aggregates are significantly different because an
- array aggregate is either all positional (with a possible others at
- the end), or all named.
-
- 7 In the record_component_association_list for a record_aggregate, if
- there is only one association, it shall be a named association.
-
- 7.a Reason: Otherwise the construct would be interpreted as a
- parenthesized expression. This is considered a syntax rule, since it
- is relevant to overload resolution. We choose not to express it with
- BNF so we can share the definition of record_component_association_
- list in both record_aggregate and extension_aggregate.
-
- 7.b Ramification: The record_component_association_list of an
- extension_aggregate does not have such a restriction.
- Name Resolution Rules
-
- 8 {expected type [record_aggregate]} The expected type for a record_
- aggregate shall be a single nonlimited record type or record extension.
-
- 8.a Ramification: This rule is used to resolve whether an
- aggregate is an array_aggregate or a record_aggregate. The presence
- of a with is used to resolve between a record_aggregate and an
- extension_aggregate.
-
- 9 {needed component (record_aggregate record_component_association_list)}
- For the record_component_association_list of a record_aggregate, all
- components of the composite value defined by the aggregate are needed[; for
- the association list of an extension_aggregate, only those components not
- determined by the ancestor expression or subtype are needed (see 4.3.2).]
- Each selector_name in a record_component_association shall denote a needed
- component [(including possibly a discriminant)].
-
- 9.a Ramification: For the association list of a record_aggregate,
- ``needed components'' includes every component of the composite
- value, but does not include those in unchosen variants (see AI-309).
- If there are variants, then the value specified for the discriminant
- that governs them determines which variant is chosen, and hence which
- components are needed.
-
- 9.b If an extension defines a new known_discriminant_part, then all
- of its discriminants are needed in the component association list of
- an extension aggregate for that type, even if the discriminants have
- the same names and types as discriminants of the type of the ancestor
- expression. This is necessary to ensure that the positions in the
- record_component_association_list are well defined, and that
- discriminants that govern variant_parts can be given by static
- expressions.
-
- 10 {expected type [record_component_association expression]} The expected
- type for the expression of a record_component_association is the type of the
- associated component(s); {associated components (of a record_component_
- association)} the associated component(s) are as follows:
-
- 11 For a positional association, the component [(including possibly
- a discriminant)] in the corresponding relative position (in the
- declarative region of the type), counting only the needed
- components;
-
- 11.a Ramification: This means that for an association list of an
- extension_aggregate, only noninherited components are counted to
- determine the position.
-
- 12 For a named association with one or more component_selector_
- names, the named component(s);
-
- 13 For a named association with the reserved word others, all needed
- components that are not associated with some previous
- association.
-
-
- Legality Rules
-
- 14 If the type of a record_aggregate is a record extension, then it shall
- be a descendant of a record type, through one or more record extensions (and
- no private extensions).
-
- 15 If there are no components needed in a given record_component_
- association_list, then the reserved words null record shall appear rather
- than a list of record_component_associations.
-
- 15.a Ramification: For example, "(null record)" is a record_
- aggregate for a null record type. Similarly, "(T'(A) with null
- record)" is an extension_aggregate for a type defined as a null
- record extension of T.
-
- 16 Each record_component_association shall have at least one associated
- component, and each needed component shall be associated with exactly one
- record_component_association. If a record_component_association has two or
- more associated components, all of them shall be of the same type.
-
- 16.a Ramification: These rules apply to an association with an
- others choice.
-
- 16.b Reason: Without these rules, there would be no way to know
- what was the expected type for the expression of the association.
-
- 16.c Discussion: AI-00244 also requires that the expression shall
- be legal for each associated component. This is because even though
- two components have the same type, they might have different
- subtypes. Therefore, the legality of the expression, particularly if
- it is an array aggregate, might differ depending on the associated
- component's subtype. However, we have relaxed the rules on array
- aggregates slightly for Ada 9X, so the staticness of an applicable
- index constraint has no effect on the legality of the array aggregate
- to which it applies. See 4.3.3. This was the only case (that we
- know of) where a subtype provided by context affected the legality of
- an expression.
-
- 16.d Ramification: The rule that requires at least one associated
- component for each record_component_association implies that there
- can be no extra associations for components that don't exist in the
- composite value, or that are already determined by the ancestor
- expression or subtype of an extension_aggregate.
-
- 16.e The second part of the first sentence ensures that no needed
- components are left out, nor specified twice.
-
- 17 If the components of a variant_part are needed, then the value of a
- discriminant that governs the variant_part shall be given by a static
- expression.
-
- 17.a Ramification: This expression might either be given within
- the aggregate itself, or in a constraint on the parent subtype in a
- derived_type_definition for some ancestor of the type of the
- aggregate.
-
-
- Dynamic Semantics
-
- 18 {evaluation [record_aggregate]} The evaluation of a record_aggregate
- consists of the evaluation of the record_component_association_list.
-
- 19 {evaluation [record_component_association_list]} For the evaluation of a
- record_component_association_list, any per-object constraints (see 3.8) for
- components specified in the association list are elaborated and any
- expressions are evaluated and converted to the subtype of the associated
- component. {implicit subtype conversion [expressions in aggregate]}
-
- 19.a Ramification: The conversion might raise Constraint_Error.
-
- 19.b Discussion: This check presumably happened as part of the
- dependent compatibility check in Ada 83.
-
- Any constraint elaborations and expression evaluations (and conversions)
- occur in an arbitrary order, except that the expression for a discriminant is
- evaluated (and converted) prior to the elaboration of any per-object
- constraint that depends on it, which in turn occurs prior to the evaluation
- and conversion of the expression for the component with the per-object
- constraint.
-
- 20 The expression of a record_component_association is evaluated (and
- converted) once for each associated component.
-
-
- NOTES
- 21 (7) For a record_aggregate with positional associations, expressions
- specifying discriminant values appear first since the known_
- discriminant_part is given first in the declaration of the type; they
- have to be in the same order as in the known_discriminant_part.
-
-
- Examples
-
- 22 Example of a record aggregate with positional associations:
-
- 23 (4, July, 1776) -- see 3.8
-
- 24 Examples of record aggregates with named associations:
-
- 25 (Day => 4, Month => July, Year => 1776)
- (Month => July, Day => 4, Year => 1776)
-
- 26 (Disk, Closed, Track => 5, Cylinder => 12) -- see 3.8.1
- (Unit => Disk, Status => Closed, Cylinder => 9, Track => 1)
-
- 27 Example of component association with several choices:
-
- 28 (Value => 0, Succ|Pred => new Cell'(0, null, null)) -- see 3.10.1
-
- 29 -- The allocator is evaluated twice: Succ and Pred designate different c\
- ells
-
- 30 Examples of record aggregates for tagged types (see 3.9 and 3.9.1):
-
- 31 Expression'(null record)
- Literal'(Value => 0.0)
- Painted_Point'(0.0, Pi/2.0, Paint => Red)
-
-
- Extensions to Ada 83
-
- 31.a {extensions to Ada 83} Null record aggregates may now be
- specified, via "(null record)". However, this syntax is more useful
- for null record extensions in extension aggregates.
-
- Wording Changes From Ada 83
-
- 31.b Various AIs have been incorporated (AI-189, AI-244, and
- AI-309). In particular, Ada 83 did not explicitly disallow extra
- values in a record aggregate. Now we do.
-
-
-
- 4.3.2 Extension Aggregates
-
- 1 [An extension_aggregate specifies a value for a type that is a record
- extension by specifying a value or subtype for an ancestor of the type,
- followed by associations for any components not determined by the ancestor_
- part.]
-
-
- Language Design Principles
-
- 1.a The model underlying this syntax is that a record extension can
- also be viewed as a regular record type with an ancestor "prefix."
- The record_component_association_list corresponds to exactly what
- would be needed if there were no ancestor/prefix type. The ancestor_
- part determines the value of the ancestor/prefix.
-
- Syntax
-
- 2 extension_aggregate ::=
- (ancestor_part with record_component_association_list)
-
- 3 ancestor_part ::= expression | subtype_mark
-
-
- Name Resolution Rules
-
- 4 {expected type [extension_aggregate]} The expected type for an extension_
- aggregate shall be a single nonlimited type that is a record extension.
- {expected type [extension_aggregate ancestor expression]} If the ancestor_
- part is an expression, it is expected to be of any nonlimited tagged type.
-
- 4.a Reason: We could have made the expected type T'Class where T
- is the ultimate ancestor of the type of the aggregate, or we could
- have made it even more specific than that. However, if the overload
- resolution rules get too complicated, the implementation gets more
- difficult and it becomes harder to produce good error messages.
-
-
- Legality Rules
-
- 5 If the ancestor_part is a subtype_mark, it shall denote a specific tagged
- subtype. The type of the extension_aggregate shall be derived from the type
- of the ancestor_part, through one or more record extensions (and no private
- extensions).
-
-
- Static Semantics
-
- 6 {needed component (extension_aggregate record_component_association_
- list)} For the record_component_association_list of an extension_aggregate,
- the only components needed are those of the composite value defined by the
- aggregate that are not inherited from the type of the ancestor_part, plus any
- inherited discriminants if the ancestor_part is a subtype_mark that denotes
- an unconstrained subtype.
-
-
- Dynamic Semantics
-
- 7 {evaluation [extension_aggregate]} For the evaluation of an extension_
- aggregate, the record_component_association_list is evaluated. If the
- ancestor_part is an expression, it is also evaluated; if the ancestor_part is
- a subtype_mark, the components of the value of the aggregate not given by the
- record_component_association_list are initialized by default as for an object
- of the ancestor type. Any implicit initializations or evaluations are
- performed in an arbitrary order, except that the expression for a
- discriminant is evaluated prior to any other evaluation or initialization
- that depends on it.
-
- 8 {Discriminant_Check [partial]} {check, language-defined (Discriminant_
- Check)} If the type of the ancestor_part has discriminants that are not
- inherited by the type of the extension_aggregate, then, unless the ancestor_
- part is a subtype_mark that denotes an unconstrained subtype, a check is made
- that each discriminant of the ancestor has the value specified for a
- corresponding discriminant, either in the record_component_association_list,
- or in the derived_type_definition for some ancestor of the type of the
- extension_aggregate. {Constraint_Error (raised by failure of run-time
- check)} Constraint_Error is raised if this check fails.
-
- 8.a Ramification: Corresponding and specified discriminants are
- defined in 3.7. The rules requiring static compatibility between new
- discriminants of a derived type and the parent discriminant(s) they
- constrain ensure that at most one check is required per discriminant
- of the ancestor expression.
-
-
- NOTES
- 9 (8) If all components of the value of the extension_aggregate are
- determined by the ancestor_part, then the record_component_association_
- list is required to be simply null record.
-
- 10 (9) If the ancestor_part is a subtype_mark, then its type can be
- abstract. If its type is controlled, then as the last step of
- evaluating the aggregate, the Initialize procedure of the ancestor type
- is called, unless the Initialize procedure is abstract (see 7.6).
-
-
- Examples
-
- 11 Examples of extension aggregates (for types defined in 3.9.1):
-
- 12 Painted_Point'(Point with Red)
- (Point'(P) with Paint => Black)
-
- 13 (Expression with Left => 1.2, Right => 3.4)
- Addition'(Binop with null record)
- -- presuming Binop is of type Binary_Operation
-
-
- Extensions to Ada 83
-
- 13.a {extensions to Ada 83} The extension aggregate syntax is new.
-
-
-
- 4.3.3 Array Aggregates
-
- 1 [In an array_aggregate, a value is specified for each component of an
- array, either positionally or by its index.] For a positional_array_
- aggregate, the components are given in increasing-index order, with a final
- others, if any, representing any remaining components. For a named_array_
- aggregate, the components are identified by the values covered by the
- discrete_choices. {94-4603.a}
-
-
- Language Design Principles
-
- 1.a The rules in this subclause are based on terms and rules for
- discrete_choice_lists defined in 3.8.1, ``Variant Parts and Discrete
- Choices''.
-
- Syntax
-
- 2 array_aggregate ::=
- positional_array_aggregate | named_array_aggregate
-
- 3 positional_array_aggregate ::=
- (expression, expression {, expression})
- | (expression {, expression}, others => expression)
-
- 4 named_array_aggregate ::=
- (array_component_association {, array_component_association})
-
- 5 array_component_association ::=
- discrete_choice_list => expression
-
-
- 6 {n-dimensional array_aggregate} An n-dimensional array_aggregate is one
- that is written as n levels of nested array_aggregates (or at the bottom
- level, equivalent string_literals). {subaggregate (of an array_aggregate)}
- For the multidimensional case (n >= 2) the array_aggregates (or equivalent
- string_literals) at the n-1 lower levels are called subaggregates of the
- enclosing n-dimensional array_aggregate. {array component expression} The
- expressions of the bottom level subaggregates (or of the array_aggregate
- itself if one-dimensional) are called the array component expressions of the
- enclosing n-dimensional array_aggregate.
-
- 6.a Ramification: Subaggregates do not have a type. They
- correspond to part of an array. For example, with a matrix, a
- subaggregate would correspond to a single row of the matrix. The
- definition of "n-dimensional" array_aggregate applies to sub-
- aggregates as well as aggregates that have a type.
-
- 6.b To be honest: {others choice} An others choice is the reserved
- word others as it appears in a positional_array_aggregate or as the
- discrete_choice of the discrete_choice_list in an array_component_
- association.
-
-
- Name Resolution Rules
-
- 7 {expected type [array_aggregate]} The expected type for an array_
- aggregate (that is not a subaggregate) shall be a single nonlimited array
- type. {expected type [array_aggregate component expression]} The component
- type of this array type is the expected type for each array component
- expression of the array_aggregate.
-
- 7.a Ramification: We already require a single array or record type
- or record extension for an aggregate. The above rule requiring a
- single nonlimited array type (and similar ones for record and
- extension aggregates) resolves which kind of aggregate you have.
-
- 8 {expected type [array_aggregate discrete_choice]} The expected type for
- each discrete_choice in any discrete_choice_list of a named_array_aggregate
- is the type of the corresponding index; {corresponding index (for an array_
- aggregate)} the corresponding index for an array_aggregate that is not a
- subaggregate is the first index of its type; for an (n-m)-dimensional
- subaggregate within an array_aggregate of an n-dimensional type, the
- corresponding index is the index in position m+1.
-
-
- Legality Rules
-
- 9 An array_aggregate of an n-dimensional array type shall be written as an
- n-dimensional array_aggregate.
-
- 9.a Ramification: In an m-dimensional array_aggregate [(including
- a subaggregate)], where m >= 2, each of the expressions has to be an
- (m-1)-dimensional subaggregate.
-
- 10 An others choice is allowed for an array_aggregate only if an applicable
- index constraint applies to the array_aggregate. {applicable index
- constraint} [An applicable index constraint is a constraint provided by
- certain contexts where an array_aggregate is permitted that can be used to
- determine the bounds of the array value specified by the aggregate.] Each of
- the following contexts (and none other) defines an applicable index
- constraint:
-
- 11 For an explicit_actual_parameter, an explicit_generic_actual_
- parameter, the expression of a return_statement, the initializa-
- tion expression in an object_declaration, or a default_expression
- [(for a parameter or a component)], when the nominal subtype of
- the corresponding formal parameter, generic formal parameter,
- function result, object, or component is a constrained array
- subtype, the applicable index constraint is the constraint of the
- subtype;
-
- 12 For the expression of an assignment_statement where the name
- denotes an array variable, the applicable index constraint is the
- constraint of the array variable;
-
- 12.a Reason: This case is broken out because the constraint comes
- from the actual subtype of the variable (which is always
- constrained) rather than its nominal subtype (which might be
- unconstrained).
-
- 13 For the operand of a qualified_expression whose subtype_mark
- denotes a constrained array subtype, the applicable index
- constraint is the constraint of the subtype;
-
- 14 For a component expression in an aggregate, if the component's
- nominal subtype is a constrained array subtype, the applicable
- index constraint is the constraint of the subtype;
-
- 14.a Discussion: Here, the array_aggregate with others is being used
- within a larger aggregate.
-
- 15 For a parenthesized expression, the applicable index constraint
- is that, if any, defined for the expression.
-
- 15.a Discussion: RM83 omitted this case, presumably as an oversight.
- We want to minimize situations where an expression becomes
- illegal if parenthesized.
-
- 16 The applicable index constraint applies to an array_aggregate that
- appears in such a context, as well as to any subaggregates thereof. In the
- case of an explicit_actual_parameter (or default_expression) for a call on a
- generic formal subprogram, no applicable index constraint is defined.
-
- 16.a Reason: This avoids generic contract model problems, because
- only mode conformance is required when matching actual subprograms
- with generic formal subprograms.
-
- 17 The discrete_choice_list of an array_component_association is allowed to
- have a discrete_choice that is a nonstatic expression or that is a discrete_
- range that defines a nonstatic or null range, only if it is the single
- discrete_choice of its discrete_choice_list, and there is only one array_
- component_association in the array_aggregate.
-
- 17.a Discussion: We now allow a nonstatic others choice even if
- there are other array component expressions as well.
-
- 18 In a named_array_aggregate with more than one discrete_choice, no two
- discrete_choices are allowed to cover the same value (see 3.8.1); if there is
- no others choice, the discrete_choices taken together shall exactly cover a
- contiguous sequence of values of the corresponding index type.
-
- 18.a Ramification: This implies that each component must be
- specified exactly once. See AI-309.
-
- 19 A bottom level subaggregate of a multidimensional array_aggregate of a
- given array type is allowed to be a string_literal only if the component type
- of the array type is a character type; each character of such a string_
- literal shall correspond to a defining_character_literal of the component
- type.
-
-
- Static Semantics
-
- 20 A subaggregate that is a string_literal is equivalent to one that is a
- positional_array_aggregate of the same length, with each expression being the
- character_literal for the corresponding character of the string_literal.
-
-
- Dynamic Semantics
-
- 21 {evaluation [array_aggregate]} The evaluation of an array_aggregate of a
- given array type proceeds in two steps:
-
- 22 Any discrete_choices of this aggregate and of its subaggregates
- are evaluated in an arbitrary order, and converted to the
- corresponding index type; {implicit subtype conversion [choices
- of aggregate]}
-
- 23 The array component expressions of the aggregate are evaluated in
- an arbitrary order and their values are converted to the
- component subtype of the array type; an array component
- expression is evaluated once for each associated component.
- {implicit subtype conversion [expressions of aggregate]}
-
- 23.a Ramification: Subaggregates are not separately evaluated.
- The conversion of the value of the component expressions to the
- component subtype might raise Constraint_Error.
-
- 24 {bounds (of the index range of an array_aggregate)} The bounds of the
- index range of an array_aggregate [(including a subaggregate)] are determined
- as follows:
-
- 25 For an array_aggregate with an others choice, the bounds are
- those of the corresponding index range from the applicable index
- constraint;
-
- 26 For a positional_array_aggregate [(or equivalent string_literal)]
- without an others choice, the lower bound is that of the
- corresponding index range in the applicable index constraint, if
- defined, or that of the corresponding index subtype, if not; in
- either case, the upper bound is determined from the lower bound
- and the number of expressions [(or the length of the string_
- literal)];
-
- 27 For a named_array_aggregate without an others choice, the bounds
- are determined by the smallest and largest index values covered
- by any discrete_choice_list.
-
- 27.a Reason: We don't need to say that each index value has to be
- covered exactly once, since that is a ramification of the
- general rule on aggregates that each component's value has to be
- specified exactly once.
-
- 28 {Range_Check [partial]} {check, language-defined (Range_Check)} For an
- array_aggregate, a check is made that the index range defined by its bounds
- is compatible with the corresponding index subtype.
-
- 28.a Discussion: In RM83, this was phrased more explicitly, but
- once we define "compatibility" between a range and a subtype, it
- seems to make sense to take advantage of that definition.
-
- 28.b Ramification: The definition of compatibility handles the
- special case of a null range, which is always compatible with a
- subtype. See AI-00313.
-
- 29 {Index_Check [partial]} {check, language-defined (Index_Check)} For an
- array_aggregate with an others choice, a check is made that no expression is
- specified for an index value outside the bounds determined by the applicable
- index constraint.
-
- 29.a Discussion: RM83 omitted this case, apparently through an
- oversight. AI-309 defines this as a dynamic check, even though other
- Ada 83 rules ensured that this check could be performed statically.
- We now allow an others choice to be dynamic, even if it is not the
- only choice, so this check now needs to be dynamic, in some cases.
- Also, within a generic unit, this would be a nonstatic check in some
- cases.
-
- 30 {Index_Check [partial]} {check, language-defined (Index_Check)} For a
- multidimensional array_aggregate, a check is made that all subaggregates that
- correspond to the same index have the same bounds.
-
- 30.a Ramification: No array bounds ``sliding'' is performed on
- subaggregates.
-
- 30.b Reason: If sliding were performed, it would not be obvious
- which subaggregate would determine the bounds of the corresponding
- index.
-
- 31 {Constraint_Error (raised by failure of run-time check)} The exception
- Constraint_Error is raised if any of the above checks fail.
-
-
- NOTES
- 32 (10) In an array_aggregate, positional notation may only be used with
- two or more expressions; a single expression in parentheses is
- interpreted as a parenthesized_expression. A named_array_aggregate,
- such as (1 => X), may be used to specify an array with a single
- component.
-
-
- Examples
-
- 33 Examples of array aggregates with positional associations:
-
- 34 (7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
- Table'(5, 8, 4, 1, others => 0) -- see 3.6
-
- 35 Examples of array aggregates with named associations:
-
- 36 (1 .. 5 => (1 .. 8 => 0.0)) -- two-dimensional
- (1 .. N => new Cell) -- N new cells, in particular for N = 0
-
- 37 Table'(2 | 4 | 10 => 1, others => 0)
- Schedule'(Mon .. Fri => True, others => False) -- see 3.6
- Schedule'(Wed | Sun => False, others => True)
- Vector'(1 => 2.5) -- single-component vector
-
- 38 Examples of two-dimensional array aggregates:
-
- 39 -- Three aggregates for the same value of subtype Matrix(1..2,1..3) (see 3.\
- 6):
-
- 40 ((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
- (1 => (1.1, 1.2, 1.3), 2 => (2.1, 2.2, 2.3))
- (1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3))
-
- 41 Examples of aggregates as initial values:
-
- 42 A : Table := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0); -- A(1)=7, A(10)=0{94-4\
- 667.c}
- B : Table := (2 | 4 | 10 => 1, others => 0); -- B(1)=0, B(10)=1
- C : constant Matrix := (1 .. 5 => (1 .. 8 => 0.0)); -- C'Last(1)=5, C'Last(\
- 2)=8
-
- 43 D : Bit_Vector(M .. N) := (M .. N => True); -- see 3.6
- E : Bit_Vector(M .. N) := (others => True);
- F : String(1 .. 1) := (1 => 'F'); -- a one component aggregate: same as "F"
- Extensions to Ada 83
-
- 43.a {extensions to Ada 83} We now allow "named with others"
- aggregates in all contexts where there is an applicable index
- constraint, effectively eliminating what was RM83-4.3.2(6). Sliding
- never occurs on an aggregate with others, because its bounds come
- from the applicable index constraint, and therefore already match the
- bounds of the target.
-
- 43.b The legality of an others choice is no longer affected by the
- staticness of the applicable index constraint. This substantially
- simplifies several rules, while being slightly more flexible for the
- user. It obviates the rulings of AI-244 and AI-310, while taking
- advantage of the dynamic nature of the "extra values" check required
- by AI-309.
-
- 43.c Named array aggregates are permitted even if the index type is
- descended from a formal scalar type. See 4.9 and AI-00190.
-
- Wording Changes From Ada 83
-
- 43.d We now separate named and positional array aggregate syntax,
- since, unlike other aggregates, named and positional associations
- cannot be mixed in array aggregates (except that an others choice is
- allowed in a positional array aggregate).
-
- 43.e We have also reorganized the presentation to handle
- multidimensional and one-dimensional aggregates more uniformly, and
- to incorporate the rulings of AI-19, AI-309, etc.
-
-
-
- 4.4 Expressions
-
- 1 {expression} An expression is a formula that defines the computation or
- retrieval of a value. In this International Standard, the term
- ``expression'' refers to a construct of the syntactic category expression or
- of any of the other five syntactic categories defined below. {and operator}
- {operator (and)} {or operator} {operator (or)} {xor operator} {operator
- (xor)} {and then (short-circuit control form)} {or else (short-circuit
- control form)} {= operator} {operator (=)} {equal operator} {operator
- (equal)} {/= operator} {operator (/=)} {not equal operator} {operator (not
- equal)} {< operator} {operator (<)} {less than operator} {operator (less
- than)} {<= operator} {operator (<=)} {less than or equal operator} {operator
- (less than or equal)} {> operator} {operator (>)} {greater than operator}
- {operator (greater than)} {>= operator} {operator (>=)} {greater than or
- equal operator} {operator (greater than or equal)} {in (membership test)}
- {not in (membership test)} {+ operator} {operator (+)} {plus operator}
- {operator (plus)} {- operator} {operator (-)} {minus operator} {operator
- (minus)} {& operator} {operator (&)} {ampersand operator} {operator
- (ampersand)} {concatenation operator} {operator (concatenation)} {catenation
- operator: see concatenation operator} {* operator} {operator (*)} {multiply
- operator} {operator (multiply)} {times operator} {operator (times)} {/
- operator} {operator (/)} {divide operator} {operator (divide)} {mod operator}
- {operator (mod)} {rem operator} {operator (rem)} {** operator} {operator
- (**)} {exponentiation operator} {operator (exponentiation)} {abs operator}
- {operator (abs)} {absolute value} {not operator} {operator (not)}
-
-
- Syntax
-
- 2 expression ::=
- relation {and relation} | relation {and then relation}
- | relation {or relation} | relation {or else relation}
- | relation {xor relation}
-
- 3 relation ::=
- simple_expression [relational_operator simple_expression]
- | simple_expression [not] in range
- | simple_expression [not] in subtype_mark
-
- 4 simple_expression ::= [unary_adding_operator] term {binary_adding_operator \
- term}
-
- 5 term ::= factor {multiplying_operator factor}
-
- 6 factor ::= primary [** primary] | abs primary | not primary
-
- 7 primary ::=
- numeric_literal | null | string_literal | aggregate
- | name | qualified_expression | allocator | (expression)
-
-
- Name Resolution Rules
-
- 8 A name used as a primary shall resolve to denote an object or a value.
-
- 8.a Discussion: This replaces RM83-4.4(3). We don't need to
- mention named numbers explicitly, because the name of a named number
- denotes a value. We don't need to mention attributes explicitly,
- because attributes now denote (rather than yield) values in general.
- Also, the new wording allows attributes that denote objects, which
- should always have been allowed (in case the implementation chose to
- have such a thing).
-
- 8.b Reason: It might seem odd that this is an overload resolution
- rule, but it is relevant during overload resolution. For example, it
- helps ensure that a primary that consists of only the identifier of a
- parameterless function is interpreted as a function_call rather than
- directly as a direct_name.
-
-
- Static Semantics
-
- 9 Each expression has a type; it specifies the computation or retrieval of
- a value of that type.
-
-
- Dynamic Semantics
-
- 10 {evaluation [primary that is a name]} The value of a primary that is a
- name denoting an object is the value of the object.
-
-
- Implementation Permissions
-
- 11 {Overflow_Check [partial]} {check, language-defined (Overflow_Check)}
- {Constraint_Error (raised by failure of run-time check)} For the evaluation
- of a primary that is a name denoting an object of an unconstrained numeric
- subtype, if the value of the object is outside the base range of its type,
- the implementation may either raise Constraint_Error or return the value of
- the object.
-
- 11.a Ramification: This means that if extra-range intermediates
- are used to hold the value of an object of an unconstrained numeric
- subtype, a Constraint_Error can be raised on a read of the object,
- rather than only on an assignment to it. Similarly, it means that
- computing the value of an object of such a subtype can be deferred
- until the first read of the object (presuming no side-effects other
- than failing an Overflow_Check are possible). This permission is
- over and above that provided by clause 11.6, since this allows the
- Constraint_Error to move to a different handler.
-
- 11.b Reason: This permission is intended to allow extra-range
- registers to be used efficiently to hold parameters and local
- variables, even if they might need to be transferred into smaller
- registers for performing certain predefined operations.
-
- 11.c Discussion: There is no need to mention other kinds of
- primarys, since any Constraint_Error to be raised can be ``charged''
- to the evaluation of the particular kind of primary.
-
-
- Examples
-
- 12 Examples of primaries:
-
- 13 4.0 -- real literal
- Pi -- named number
- (1 .. 10 => 0) -- array aggregate
- Sum -- variable
- Integer'Last -- attribute
- Sine(X) -- function call
- Color'(Blue) -- qualified expression
- Real(M*N) -- conversion
- (Line_Count + 10) -- parenthesized expression
-
- 14 Examples of expressions:
-
- 15 Volume -- primary
- not Destroyed -- factor
- 2*Line_Count -- term
- -4.0 -- simple expression
- -4.0 + A -- simple expression
- B**2 - 4.0*A*C -- simple expression
- Password(1 .. 3) = "Bwv" -- relation
- Count in Small_Int -- relation
- Count not in Small_Int -- relation
- Index = 0 or Item_Hit -- expression
- (Cold and Sunny) or Warm -- expression (parentheses are required)
- A**(B**C) -- expression (parentheses are required)
-
-
- Extensions to Ada 83
-
- 15.a {extensions to Ada 83} In Ada 83, out parameters and their
- nondiscriminant subcomponents are not allowed as primaries. These
- restrictions are eliminated in Ada 9X.
-
- 15.b In various contexts throughout the language where Ada 83
- syntax rules had simple_expression, the corresponding Ada 9X syntax
- rule has expression instead. This reflects the inclusion of modular
- integer types, which makes the logical operators "and", "or", and
- "xor" more useful in expressions of an integer type. Requiring
- parentheses to use these operators in such contexts seemed
- unnecessary and potentially confusing. Note that the bounds of a
- range still have to be specified by simple_expressions, since
- otherwise expressions involving membership tests might be ambiguous.
- Essentially, the operation ".." is of higher precedence than the
- logical operators, and hence uses of logical operators still have to
- be parenthesized when used in a bound of a range.
-
-
-
- 4.5 Operators and Expression Evaluation
-
- 1 [{precedence of operators} {operator precedence} The language defines the
- following six categories of operators (given in order of increasing
- precedence). The corresponding operator_symbols, and only those, can be used
- as designators in declarations of functions for user-defined operators. See
- 6.6, ``Overloading of Operators''.]
- Syntax
-
- 2 logical_operator ::= and | or | xor
-
- 3 relational_operator ::= = | /= | < \
- | <= | > | >=
-
- 4 binary_adding_operator ::= + | - | &
-
- 5 unary_adding_operator ::= + | -
-
- 6 multiplying_operator ::= * | / | mod \
- | rem
-
- 7 highest_precedence_operator ::= ** | abs | not
-
- 7.a Discussion: Some of the above syntactic categories are not
- used in other syntax rules. They are just used for classification.
- The others are used for both classification and parsing.
-
-
- Static Semantics
-
- 8 For a sequence of operators of the same precedence level, the operators
- are associated with their operands in textual order from left to right.
- Parentheses can be used to impose specific associations.
-
- 8.a Discussion: The left-associativity is not directly inherent in
- the grammar of 4.4, though in 1.1.4 the definition of the metasymbols
- {} implies left associativity. So this could be seen as redundant,
- depending on how literally one interprets the definition of the {}
- metasymbols.
-
- 8.b See the Implementation Permissions below regarding flexibility
- in reassociating operators of the same precedence.
-
- 9 {predefined operator} {operator (predefined)} For each form of type
- definition, certain of the above operators are predefined; that is, they are
- implicitly declared immediately after the type definition. {binary operator}
- {operator (binary)} {unary operator} {operator (unary)} For each such
- implicit operator declaration, the parameters are called Left and Right for
- binary operators; the single parameter is called Right for unary operators.
- [An expression of the form X op Y, where op is a binary operator, is
- equivalent to a function_call of the form "op"(X, Y). An expression of the
- form op Y, where op is a unary operator, is equivalent to a function_call of
- the form "op"(Y). The predefined operators and their effects are described
- in subclauses 4.5.1 through 4.5.6.]
-
-
- Dynamic Semantics
-
- 10 [{Constraint_Error (raised by failure of run-time check)} The predefined
- operations on integer types either yield the mathematically correct result or
- raise the exception Constraint_Error. For implementations that support the
- Numerics Annex, the predefined operations on real types yield results whose
- accuracy is defined in Annex G, or raise the exception Constraint_Error.
- {94-4481.a}]
-
- 10.a To be honest: Predefined operations on real types can
- ``silently'' give wrong results when the Machine_Overflows attribute
- is false, and the computation overflows.
-
-
- Implementation Requirements
-
- 11 {Constraint_Error (raised by failure of run-time check)} The
- implementation of a predefined operator that delivers a result of an integer
- or fixed point type may raise Constraint_Error only if the result is outside
- the base range of the result type.
-
- 12 {Constraint_Error (raised by failure of run-time check)} The
- implementation of a predefined operator that delivers a result of a floating
- point type may raise Constraint_Error only if the result is outside the safe
- range of the result type.
-
- 12.a To be honest: An exception is made for exponentiation by a
- negative exponent in 4.5.6.
-
-
- Implementation Permissions
-
- 13 For a sequence of predefined operators of the same precedence level (and
- in the absence of parentheses imposing a specific association), an
- implementation may impose any association of the operators with operands so
- long as the result produced is an allowed result for the left-to-right
- association, but ignoring the potential for failure of language-defined
- checks in either the left-to-right or chosen order of association.
-
- 13.a Discussion: Note that the permission to reassociate the
- operands in any way subject to producing a result allowed for the
- left-to-right association is not much help for most floating point
- operators, since reassociation may introduce significantly different
- round-off errors, delivering a result that is outside the model
- interval for the left-to-right association. Similar problems arise
- for division with integer or fixed point operands.
-
- 13.b Note that this permission does not apply to user-defined
- operators.
-
-
- NOTES
- 14 (11) The two operands of an expression of the form X op Y, where op is a
- binary operator, are evaluated in an arbitrary order, as for any
- function_call (see 6.4).
-
-
- Examples
-
- 15 Examples of precedence:
-
- 16 not Sunny or Warm -- same as (not Sunny) or Warm
- X > 4.0 and Y > 0.0 -- same as (X > 4.0) and (Y > 0.0)
-
- 17 -4.0*A**2 -- same as -(4.0 * (A**2))
- abs(1 + A) + B -- same as (abs (1 + A)) + B
- Y**(-3) -- parentheses are necessary
- A / B * C -- same as (A/B)*C
- A + (B + C) -- evaluate B + C before adding it to A
-
-
- Wording Changes From Ada 83
-
- 17.a We don't give a detailed definition of precedence, since it is
- all implicit in the syntax rules anyway.
-
- 17.b The permission to reassociate is moved here from RM83-11.6(5),
- so it is closer to the rules defining operator association.
-
-
-
- 4.5.1 Logical Operators and Short-circuit Control Forms
-
- Name Resolution Rules
-
- 1 {short-circuit control form} {and then (short-circuit control form)} {or
- else (short-circuit control form)} An expression consisting of two relations
- connected by and then or or else (a short-circuit control form) shall resolve
- to be of some boolean type; {expected type [short-circuit control form
- relation]} the expected type for both relations is that same boolean type.
-
- 1.a Reason: This rule is written this way so that overload
- resolution treats the two operands symmetrically; the resolution of
- overloading present in either one can benefit from the resolution of
- the other. Furthermore, the type expected by context can help.
-
-
- Static Semantics
-
- 2 {logical operator} {operator (logical)} {and operator} {operator (and)}
- {or operator} {operator (or)} {xor operator} {operator (xor)} The following
- logical operators are predefined for every boolean type T, for every modular
- type T, and for every one-dimensional array type T whose component type is a
- boolean type: {bit string: see logical operators on boolean arrays}
-
- 3
- function "and"(Left, Right : T) return T
- function "or" (Left, Right : T) return T
- function "xor"(Left, Right : T) return T
-
- 3.a To be honest: For predefined operators, the parameter and
- result subtypes shown as T are actually the unconstrained subtype of
- the type.
-
- 4 For boolean types, the predefined logical operators and, or, and xor
- perform the conventional operations of conjunction, inclusive disjunction,
- and exclusive disjunction, respectively.
-
- 5 For modular types, the predefined logical operators are defined on a
- bit-by-bit basis, using the binary representation of the value of the
- operands to yield a binary representation for the result, where zero
- represents False and one represents True. If this result is outside the base
- range of the type, a final subtraction by the modulus is performed to bring
- the result into the base range of the type.
-
- 6 The logical operators on arrays are performed on a component-by-component
- basis on matching components (as for equality -- see 4.5.2), using the
- predefined logical operator for the component type. The bounds of the
- resulting array are those of the left operand.
-
-
- Dynamic Semantics
-
- 7 {evaluation [short-circuit control form]} The short-circuit control forms
- and then and or else deliver the same result as the corresponding predefined
- and and or operators for boolean types, except that the left operand is
- always evaluated first, and the right operand is not evaluated if the value
- of the left operand determines the result.
-
- 8 {Length_Check [partial]} {check, language-defined (Length_Check)} For the
- logical operators on arrays, a check is made that for each component of the
- left operand there is a matching component of the right operand, and vice
- versa. {Range_Check [partial]} {check, language-defined (Range_Check)} Also,
- a check is made that each component of the result belongs to the component
- subtype. {Constraint_Error (raised by failure of run-time check)} The
- exception Constraint_Error is raised if either of the above checks fails.
-
- 8.a Discussion: The check against the component subtype is per
- AI-00535.
- NOTES
- 9 (12) The conventional meaning of the logical operators is given by the
- following truth table:
-
- 10
- A B (A and B) (A or B) (A \
- xor B)
-
- True True True True \
- False
- True False False True \
- True
- False True False True \
- True
- False False False False \
- False
-
-
- Examples
-
- 11 Examples of logical operators:
-
- 12 Sunny or Warm
- Filter(1 .. 10) and Filter(15 .. 24) -- see 3.6.1
-
- 13 Examples of short-circuit control forms:
-
- 14 Next_Car.Owner /= null and then Next_Car.Owner.Age > 25 -- see 3.10.1
- N = 0 or else A(N) = Hit_Value
-
-
-
- 4.5.2 Relational Operators and Membership Tests
-
- 1 [{relational operator} {operator (relational)} {comparison operator: see
- relational operator} {equality operator} {operator (equality)} The equality
- operators = (equals) and /= (not equals) are predefined for nonlimited types.
- {ordering operator} {operator (ordering)} The other relational_operators are
- the ordering operators < (less than), <= (less than or equal), > (greater
- than), and >= (greater than or equal). {= operator} {operator (=)} {equal
- operator} {operator (equal)} {/= operator} {operator (/=)} {not equal
- operator} {operator (not equal)} {< operator} {operator (<)} {less than
- operator} {operator (less than)} {<= operator} {operator (<=)} {less than or
- equal operator} {operator (less than or equal)} {> operator} {operator (>)}
- {greater than operator} {operator (greater than)} {>= operator} {operator
- (>=)} {greater than or equal operator} {operator (greater than or equal)}
- {discrete array type} The ordering operators are predefined for scalar types,
- and for discrete array types, that is, one-dimensional array types whose
- components are of a discrete type.
-
- 1.a Ramification: The equality operators are not defined for every
- nonlimited type -- see below for the exact rule.
-
- 2 {membership test} {in (membership test)} {not in (membership test)} A
- membership test, using in or not in, determines whether or not a value
- belongs to a given subtype or range, or has a tag that identifies a type that
- is covered by a given type. Membership tests are allowed for all types.]
-
-
- Name Resolution Rules
-
- 3 {expected type [membership test simple_expression]} {tested type (of a
- membership test)} The tested type of a membership test is the type of the
- range or the type determined by the subtype_mark. If the tested type is
- tagged, then the simple_expression shall resolve to be of a type that covers
- or is covered by the tested type; if untagged, the expected type for the
- simple_expression is the tested type.
-
- 3.a Reason: The part of the rule for untagged types is stated in a
- way that ensures that operands like null are still legal as operands
- of a membership test.
-
- 3.b The significance of ``covers or is covered by'' is that we
- allow the simple_expression to be of any class-wide type that covers
- the tested type, not just the one rooted at the tested type.
-
-
- Legality Rules
-
- 4 For a membership test, if the simple_expression is of a tagged class-wide
- type, then the tested type shall be (visibly) tagged.
-
- 4.a Ramification: Untagged types covered by the tagged class-wide
- type are not permitted. Such types can exist if they are descendants
- of a private type whose full type is tagged. This rule is intended
- to avoid confusion since such derivatives don't have their ``own''
- tag, and hence are indistinguishable from one another at run time
- once converted to a covering class-wide type.
-
-
- Static Semantics
-
- 5 The result type of a membership test is the predefined type Boolean.
-
- 6 The equality operators are predefined for every specific type T that is
- not limited, and not an anonymous access type, with the following
- specifications:
-
- 7 function "=" (Left, Right : T) return Boolean
- function "/="(Left, Right : T) return Boolean
-
- 8 The ordering operators are predefined for every specific scalar type T,
- and for every discrete array type T, with the following specifications:
-
- 9 function "<" (Left, Right : T) return Boolean
- function "<="(Left, Right : T) return Boolean
- function ">" (Left, Right : T) return Boolean
- function ">="(Left, Right : T) return Boolean
-
-
- Dynamic Semantics
-
- 10 For discrete types, the predefined relational operators are defined in
- terms of corresponding mathematical operations on the position numbers of the
- values of the operands.
-
- 11 For real types, the predefined relational operators are defined in terms
- of the corresponding mathematical operations on the values of the operands,
- subject to the accuracy of the type.
-
- 11.a Ramification: For floating point types, the results of
- comparing nearly equal values depends on the accuracy of the
- implementation (see G.2.1, ``Model of Floating Point Arithmetic'' for
- implementations that support the Numerics Annex). {94-4481.a}
-
- 11.b Implementation Note: On a machine with signed zeros, if the
- generated code generates both plus zero and minus zero, plus and
- minus zero must be equal by the predefined equality operators.
- {94-4539.c}
-
- 12 Two access-to-object values are equal if they designate the same object,
- or if both are equal to the null value of the access type.
-
- 13 Two access-to-subprogram values are equal if they are the result of the
- same evaluation of an Access attribute_reference, or if both are equal to the
- null value of the access type. Two access-to-subprogram values are unequal
- if they designate different subprograms. {unspecified [partial]} [It is
- unspecified whether two access values that designate the same subprogram but
- are the result of distinct evaluations of Access attribute_references are
- equal or unequal.]
-
- 13.a Reason: This allows each Access attribute_reference for a
- subprogram to designate a distinct ``wrapper'' subprogram if
- necessary to support an indirect call.
-
- 14 {equality operator (special inheritance rule for tagged types)} For a
- type extension, predefined equality is defined in terms of the primitive
- [(possibly user-defined)] equals operator of the parent type and of any
- tagged components of the extension part, and predefined equality for any
- other components not inherited from the parent type.
-
- 14.a Ramification: Two values of a type extension are not equal if
- there is a variant_part in the extension part and the two values have
- different variants present. This is a ramification of the
- requirement that a discriminant governing such a variant_part has to
- be a ``new'' discriminant, and so has to be equal in the two values
- for the values to be equal. Note that variant_parts in the parent
- part need not match if the primitive equals operator for the parent
- type considers them equal.
-
- 15 For a private type, if its full type is tagged, predefined equality is
- defined in terms of the primitive equals operator of the full type; if the
- full type is untagged, predefined equality for the private type is that of
- its full type.
-
- 16 {matching components} For other composite types, the predefined equality
- operators [(and certain other predefined operations on composite types -- see
- 4.5.1 and 4.6)] are defined in terms of the corresponding operation on
- matching components, defined as follows:
-
- 17 For two composite objects or values of the same non-array type,
- matching components are those that correspond to the same
- component_declaration or discriminant_specification; {94-4667.f}
-
- 18 For two one-dimensional arrays of the same type, matching
- components are those (if any) whose index values match in the
- following sense: the lower bounds of the index ranges are defined
- to match, and the successors of matching indices are defined to
- match;
-
- 19 For two multidimensional arrays of the same type, matching
- components are those whose index values match in successive index
- positions.
-
- 20 The analogous definitions apply if the types of the two objects or
- values are convertible, rather than being the same.
-
- 20.a Discussion: Ada 83 seems to omit this part of the definition,
- though it is used in array type conversions. See 4.6.
-
- 21 Given the above definition of matching components, the result of the
- predefined equals operator for composite types (other than for those
- composite types covered earlier) is defined as follows:
-
- 22 If there are no components, the result is defined to be True;
-
- 23 If there are unmatched components, the result is defined to be
- False;
-
- 24 Otherwise, the result is defined in terms of the primitive equals
- operator for any matching tagged components, and the predefined
- equals for any matching untagged components.
-
- 24.a Reason: This asymmetry between tagged and untagged components
- is necessary to preserve upward compatibility and corresponds
- with the corresponding situation with generics, where the
- predefined operations ``reemerge'' in a generic for untagged
- types, but do not for tagged types. Also, only tagged types
- support user-defined assignment (see 7.6), so only tagged types
- can fully handle levels of indirection in the implementation of
- the type. For untagged types, one reason for a user-defined
- equals operator might be to allow values with different bounds
- or discriminants to compare equal in certain cases. When such
- values are matching components, the bounds or discriminants will
- necessarily match anyway if the discriminants of the enclosing
- values match.
-
- 24.b Ramification: Two null arrays of the same type are always
- equal; two null records of the same type are always equal.
-
- 24.c Note that if a composite object has a component of a floating
- point type, and the floating point type has both a plus and minus
- zero, which are considered equal by the predefined equality, then a
- block compare cannot be used for the predefined composite equality.
- Of course, with user-defined equals operators for tagged components,
- a block compare breaks down anyway, so this is not the only special
- case that requires component-by-component comparisons. On a one's
- complement machine, a similar situation might occur for integer
- types, since one's complement machines typically have both a plus and
- minus (integer) zero.
-
- 25 The predefined "/=" operator gives the complementary result to the
- predefined "=" operator.
-
- 25.a Ramification: Furthermore, if the user defines an "="
- operator that returns Boolean, then a "/=" operator is implicitly
- declared in terms of the user-defined "=" operator so as to give the
- complementary result. See 6.6.
-
- 26 {lexicographic order} For a discrete array type, the predefined ordering
- operators correspond to lexicographic order using the predefined order
- relation of the component type: A null array is lexicographically less than
- any array having at least one component. In the case of nonnull arrays, the
- left operand is lexicographically less than the right operand if the first
- component of the left operand is less than that of the right; otherwise the
- left operand is lexicographically less than the right operand only if their
- first components are equal and the tail of the left operand is
- lexicographically less than that of the right (the tail consists of the
- remaining components beyond the first and can be null).
-
- 27 {evaluation [membership test]} For the evaluation of a membership test,
- the simple_expression and the range (if any) are evaluated in an arbitrary
- order.
-
- 28 A membership test using in yields the result True if:
-
- 29 The tested type is scalar, and the value of the simple_expression
- belongs to the given range, or the range of the named subtype; or
-
- 29.a Ramification: The scalar membership test only does a range
- check. It does not perform any other check, such as whether a
- value falls in a ``hole'' of a ``holey'' enumeration type. The
- Pos attribute function can be used for that purpose.
-
- 29.b Even though Standard.Float is an unconstrained subtype, the test
- ``X in Float'' will still return False (presuming the evaluation
- of X does not raise Constraint_Error) when X is outside
- Float'Range.
-
- 30 The tested type is not scalar, and the value of the simple_
- expression satisfies any constraints of the named subtype, and,
- if the type of the simple_expression is class-wide, the value has
- a tag that identifies a type covered by the tested type.
-
- 30.a Ramification: Note that the tag is not checked if the simple_
- expression is of a specific type.
-
- 31 Otherwise the test yields the result False.
-
- 32 A membership test using not in gives the complementary result to the
- corresponding membership test using in.
-
-
- NOTES
- 33 (13) No exception is ever raised by a membership test, by a predefined
- ordering operator, or by a predefined equality operator for an
- elementary type, but an exception can be raised by the evaluation of the
- operands. A predefined equality operator for a composite type can only
- raise an exception if the type has a tagged part whose primitive equals
- operator propagates an exception.
-
- 34 (14) If a composite type has components that depend on discriminants,
- two values of this type have matching components if and only if their
- discriminants are equal. Two nonnull arrays have matching components if
- and only if the length of each dimension is the same for both.
-
-
- Examples
-
- 35 Examples of expressions involving relational operators and membership
- tests:
-
- 36 X /= Y
-
- 37 "" < "A" and "A" < "Aa" -- True
- "Aa" < "B" and "A" < "A " -- True
-
- 38 My_Car = null -- true if My_Car has been set to null (see 3.1\
- 0.1)
- My_Car = Your_Car -- true if we both share the same car
- My_Car.all = Your_Car.all -- true if the two cars are identical
-
- 39 N not in 1 .. 10 -- range membership test
- Today in Mon .. Fri -- range membership test
- Today in Weekday -- subtype membership test (see 3.5.1)
- Archive in Disk_Unit -- subtype membership test (see 3.8.1)
- Tree.all in Addition'Class -- class membership test (see 3.9.1)
-
-
- Extensions to Ada 83
-
- 39.a {extensions to Ada 83} Membership tests can be used to test
- the tag of a class-wide value.
-
- 39.b Predefined equality for a composite type is defined in terms
- of the primitive equals operator for tagged components or the parent
- part.
-
- Wording Changes From Ada 83
-
- 39.c The term ``membership test'' refers to the relation "X in S"
- rather to simply the reserved word in or not in.
-
- 39.d We use the term ``equality operator'' to refer to both the =
- (equals) and /= (not equals) operators. Ada 83 referred to = as the
- equality operator, and /= as the inequality operator. The new
- wording is more consistent with the ISO 10646 name for "=" (equals
- sign) and provides a category similar to ``ordering operator'' to
- refer to both = and /=.
-
- 39.e We have changed the term ``catenate'' to ``concatenate''.
-
-
-
- 4.5.3 Binary Adding Operators
-
- Static Semantics
-
- 1 {binary adding operator} {operator (binary adding)} {+ operator}
- {operator (+)} {plus operator} {operator (plus)} {- operator} {operator (-)}
- {minus operator} {operator (minus)} The binary adding operators + (addition)
- and - (subtraction) are predefined for every specific numeric type T with
- their conventional meaning. They have the following specifications:
-
- 2 function "+"(Left, Right : T) return T
- function "-"(Left, Right : T) return T
-
- 3 {& operator} {operator (&)} {ampersand operator} {operator (ampersand)}
- {concatenation operator} {operator (concatenation)} {catenation operator: see
- concatenation operator} The concatenation operators & are predefined for
- every nonlimited, one-dimensional array type T with component type C. They
- have the following specifications:
-
- 4 function "&"(Left : T; Right : T) return T
- function "&"(Left : T; Right : C) return T
- function "&"(Left : C; Right : T) return T
- function "&"(Left : C; Right : C) return T
-
-
- Dynamic Semantics
-
- 5 {evaluation [concatenation]} For the evaluation of a concatenation with
- result type T, if both operands are of type T, the result of the
- concatenation is a one-dimensional array whose length is the sum of the
- lengths of its operands, and whose components comprise the components of the
- left operand followed by the components of the right operand. If the left
- operand is a null array, the result of the concatenation is the right
- operand. Otherwise, the lower bound of the result is determined as follows:
-
- 6 If the ultimate ancestor of the array type was defined by a
- constrained_array_definition, then the lower bound of the result
- is that of the index subtype;
-
- 6.a Reason: This rule avoids Constraint_Error when using
- concatenation on an array type whose first subtype is
- constrained.
-
- 7 If the ultimate ancestor of the array type was defined by an
- unconstrained_array_definition, then the lower bound of the
- result is that of the left operand.
-
- 8 [The upper bound is determined by the lower bound and the length.]
- {Index_Check [partial]} {check, language-defined (Index_Check)} A check is
- made that the upper bound of the result of the concatenation belongs to the
- range of the index subtype, unless the result is a null array. {Constraint_
- Error (raised by failure of run-time check)} Constraint_Error is raised if
- this check fails.
-
- 9 If either operand is of the component type C, the result of the
- concatenation is given by the above rules, using in place of such an operand
- an array having this operand as its only component (converted to the
- component subtype) and having the lower bound of the index subtype of the
- array type as its lower bound. {implicit subtype conversion [operand of
- concatenation]}
- 9.a Ramification: The conversion might raise Constraint_Error.
- The conversion provides ``sliding'' for the component in the case of
- an array-of-arrays, consistent with the normal Ada 9X rules that
- allow sliding during parameter passing.
-
- 10 {assignment operation (during evaluation of concatenation)} The result
- of a concatenation is defined in terms of an assignment to an anonymous
- object, as for any function call (see 6.5).
-
- 10.a Ramification: This implies that value adjustment is performed
- as appropriate -- see 7.6. We don't bother saying this for other
- predefined operators, even though they are all function calls,
- because this is the only one where it matters. It is the only one
- that can return a value having controlled parts.
-
-
- NOTES
- 11 (15) As for all predefined operators on modular types, the binary adding
- operators + and - on modular types include a final reduction modulo the
- modulus if the result is outside the base range of the type.
-
- 11.a Implementation Note: A full "modulus" operation need not be
- performed after addition or subtraction of modular types. For binary
- moduli, a simple mask is sufficient. For nonbinary moduli, a check
- after addition to see if the value is greater than the high bound of
- the base range can be followed by a conditional subtraction of the
- modulus. Conversely, a check after subtraction to see if a "borrow"
- was performed can be followed by a conditional addition of the
- modulus.
-
-
- Examples
-
- 12 Examples of expressions involving binary adding operators:
-
- 13 Z + 0.1 -- Z has to be of a real type
-
- 14 "A" & "BCD" -- concatenation of two string literals
- 'A' & "BCD" -- concatenation of a character literal and a string literal
- 'A' & 'A' -- concatenation of two character literals
-
-
- Inconsistencies With Ada 83
-
- 14.a {inconsistencies with Ada 83} The lower bound of the result of
- concatenation, for a type whose first subtype is constrained, is now
- that of the index subtype. This is inconsistent with Ada 83, but
- generally only for Ada 83 programs that raise Constraint_Error. For
- example, the concatenation operator in
-
- 14.b X : array(1..10) of Integer;
- begin
- X := X(6..10) & X(1..5);
-
- 14.c would raise Constraint_Error in Ada 83 (because the bounds of
- the result of the concatenation would be 6..15, which is outside of
- 1..10), but would succeed and swap the halves of X (as expected) in
- Ada 9X.
-
- Extensions to Ada 83
-
- 14.d {extensions to Ada 83} Concatenation is now useful for array
- types whose first subtype is constrained. When the result type of a
- concatenation is such an array type, Constraint_Error is avoided by
- effectively first sliding the left operand (if nonnull) so that its
- lower bound is that of the index subtype.
-
-
-
- 4.5.4 Unary Adding Operators
-
- Static Semantics
-
- 1 {unary adding operator} {operator (unary adding)} {+ operator} {operator
- (+)} {plus operator} {operator (plus)} {- operator} {operator (-)} {minus
- operator} {operator (minus)} The unary adding operators + (identity) and -
- (negation) are predefined for every specific numeric type T with their
- conventional meaning. They have the following specifications:
-
- 2 function "+"(Right : T) return T
- function "-"(Right : T) return T
-
-
- NOTES
- 3 (16) For modular integer types, the unary adding operator -, when given
- a nonzero operand, returns the result of subtracting the value of the
- operand from the modulus; for a zero operand, the result is zero.
-
-
-
- 4.5.5 Multiplying Operators
-
- Static Semantics
-
- 1 {multiplying operator} {operator (multiplying)} {* operator} {operator
- (*)} {multiply operator} {operator (multiply)} {times operator} {operator
- (times)} {/ operator} {operator (/)} {divide operator} {operator (divide)}
- {mod operator} {operator (mod)} {rem operator} {operator (rem)} The
- multiplying operators * (multiplication), / (division), mod (modulus), and
- rem (remainder) are predefined for every specific integer type T:
-
- 2 function "*" (Left, Right : T) return T
- function "/" (Left, Right : T) return T
- function "mod"(Left, Right : T) return T
- function "rem"(Left, Right : T) return T
-
- 3 Signed integer multiplication has its conventional meaning.
-
- 4 Signed integer division and remainder are defined by the relation:
-
- 5 A = (A/B)*B + (A rem B)
-
- 6 where (A rem B) has the sign of A and an absolute value less than the
- absolute value of B. Signed integer division satisfies the identity:
-
- 7 (-A)/B = -(A/B) = A/(-B)
-
- 8 The signed integer modulus operator is defined such that the result of A
- mod B has the sign of B and an absolute value less than the absolute value of
- B; in addition, for some signed integer value N, this result satisfies the
- relation:
-
- 9 A = B*N + (A mod B)
-
- 10 [The multiplying operators on modular types are defined in terms of the
- corresponding signed integer operators, followed by a reduction modulo the
- modulus if the result is outside the base range of the type [(which is only
- possible for the "*" operator)].]
-
- 10.a Ramification: The above identity satisfied by signed integer
- division is not satisfied by modular division because of the
- difference in effect of negation.
-
- 11 Multiplication and division operators are predefined for every specific
- floating point type T:
-
- 12 function "*"(Left, Right : T) return T
- function "/"(Left, Right : T) return T
-
- 13 The following multiplication and division operators, with an operand of
- the predefined type Integer, are predefined for every specific fixed point
- type T:
-
- 14 function "*"(Left : T; Right : Integer) return T
- function "*"(Left : Integer; Right : T) return T
- function "/"(Left : T; Right : Integer) return T
-
- 15 [All of the above multiplying operators are usable with an operand of an
- appropriate universal numeric type.] The following additional multiplying
- operators for root_real are predefined[, and are usable when both operands
- are of an appropriate universal or root numeric type, and the result is
- allowed to be of type root_real, as in a number_declaration]:
-
- 15.a Ramification: These operators are analogous to the
- multiplying operators involving fixed or floating point types where
- root_real substitutes for the fixed or floating point type, and root_
- integer substitutes for Integer. Only values of the corresponding
- universal numeric types are implicitly convertible to these root
- numeric types, so these operators are really restricted to use with
- operands of a universal type, or the specified root numeric types.
-
- 16 function "*"(Left, Right : root_real) return root_real
- function "/"(Left, Right : root_real) return root_real
-
- 17 function "*"(Left : root_real; Right : root_integer) return root_real
- function "*"(Left : root_integer; Right : root_real) return root_real
- function "/"(Left : root_real; Right : root_integer) return root_real
-
- 18 Multiplication and division between any two fixed point types are
- provided by the following two predefined operators:
-
- 18.a Ramification: Universal_fixed is the universal type for the
- class of fixed point types, meaning that these operators take
- operands of any fixed point types (not necessarily the same) and
- return a result that is implicitly (or explicitly) convertible to any
- fixed point type.
-
- 19 function "*"(Left, Right : universal_fixed) return universal_fixed
- function "/"(Left, Right : universal_fixed) return universal_fixed
-
-
- Legality Rules
-
- 20 The above two fixed-fixed multiplying operators shall not be used in a
- context where the expected type for the result is itself universal_fixed --
- [the context has to identify some other numeric type to which the result is
- to be converted, either explicitly or implicitly].
-
- 20.a Discussion: The small of universal_fixed is infinitesimal; no
- loss of precision is permitted. However, fixed-fixed division is
- impractical to implement when an exact result is required, and
- multiplication will sometimes result in unanticipated overflows in
- such circumstances, so we require an explicit conversion to be
- inserted in expressions like A * B * C if A, B, and C are each of
- some fixed point type.
-
- 20.b On the other hand, X := A * B; is permitted by this rule, even
- if X, A, and B are all of different fixed point types, since the
- expected type for the result of the multiplication is the type of X,
- which is necessarily not universal_fixed.
- Dynamic Semantics
-
- 21 The multiplication and division operators for real types have their
- conventional meaning.[For floating point types, the accuracy of the result is
- determined by the precision of the result type. For decimal fixed point
- types, the result is truncated toward zero if the mathematical result is
- between two multiples of the small of the specific result type (possibly
- determined by context); for ordinary fixed point types, if the mathematical
- result is between two multiples of the small, it is unspecified which of the
- two is the result. {unspecified [partial]}]
-
- 22 {Division_Check [partial]} {check, language-defined (Division_Check)}
- {Constraint_Error (raised by failure of run-time check)} The exception
- Constraint_Error is raised by integer division, rem, and mod if the right
- operand is zero. [Similarly, for a real type T with T'Machine_Overflows
- True, division by zero raises Constraint_Error.]
-
-
- NOTES
- 23 (17) For positive A and B, A/B is the quotient and A rem B is the
- remainder when A is divided by B. The following relations are satisfied
- by the rem operator:
-
- 24 A rem (-B) = A rem B
- (-A) rem B = -(A rem B)
-
- 25 (18) For any signed integer K, the following identity holds:
-
- 26 A mod B = (A + K*B) mod B
-
- 27The relations between signed integer division, remainder, and
- modulus are illustrated by the following table:
-
- 28 A B A/B A rem B A mod B A B A/B A rem B A mod\
- B
-
- 29 10 5 2 0 0 -10 5 -2 0 0
- 11 5 2 1 1 -11 5 -2 -1 4
- 12 5 2 2 2 -12 5 -2 -2 3
- 13 5 2 3 3 -13 5 -2 -3 2
- 14 5 2 4 4 -14 5 -2 -4 1
-
- 30 A B A/B A rem B A mod B A B A/B A rem B A mod\
- B
- 10 -5 -2 0 0 -10 -5 2 0 0
- 11 -5 -2 1 -4 -11 -5 2 -1 -1
- 12 -5 -2 2 -3 -12 -5 2 -2 -2
- 13 -5 -2 3 -2 -13 -5 2 -3 -3
- 14 -5 -2 4 -1 -14 -5 2 -4 -4
-
-
- Examples
-
- 31 Examples of expressions involving multiplying operators:
-
- 32 I : Integer := 1;
- J : Integer := 2;
- K : Integer := 3;
-
- 33 X : Real := 1.0; -- see 3.5.7
- Y : Real := 2.0;
-
- 34 F : Fraction := 0.25; -- see 3.5.9
- G : Fraction := 0.5;
-
- 35
- Expression Value Result Type
-
- I*J 2 same as I and J, that is, Integer
- K/J 1 same as K and J, that is, Integer
- K mod J 1 same as K and J, that is, Integer
-
- X/Y 0.5 same as X and Y, that is, Real
- F/2 0.125 same as F, that is, Fraction
-
- 3*F 0.75 same as F, that is, Fraction
- 0.75*G 0.375 universal_fixed, implicitly conve\
- rtible
- to any fixed point type
- Fraction(F*G) 0.125 Fraction, as stated by the conver\
- sion
- Real(J)*Y 4.0 Real, the type of both operands a\
- fter
- conversion of J
-
-
- Extensions to Ada 83
-
- 35.a {extensions to Ada 83} Explicit conversion of the result of
- multiplying or dividing two fixed point numbers is no longer
- required, provided the context uniquely determines some specific
- fixed point result type. This is to improve support for decimal
- fixed point, where requiring explicit conversion on every fixed-fixed
- multiply or divide was felt to be inappropriate.
-
- 35.b The type universal_fixed is covered by universal_real, so real
- literals and fixed point operands may be multiplied or divided
- directly, without any explicit conversions required.
-
- Wording Changes From Ada 83
-
- 35.c We have used the normal syntax for function definition rather
- than a tabular format.
-
-
-
- 4.5.6 Highest Precedence Operators
-
- Static Semantics
-
- 1 {highest precedence operator} {operator (highest precedence)} {abs
- operator} {operator (abs)} {absolute value} The highest precedence unary
- operator abs (absolute value) is predefined for every specific numeric type
- T, with the following specification:
-
- 2 function "abs"(Right : T) return T
-
- 3 {not operator} {operator (not)} {logical operator: see also not operator}
- The highest precedence unary operator not (logical negation) is predefined
- for every boolean type T, every modular type T, and for every one-dimensional
- array type T whose components are of a boolean type, with the following
- specification:
-
- 4 function "not"(Right : T) return T
-
- 5 The result of the operator not for a modular type is defined as the
- difference between the high bound of the base range of the type and the value
- of the operand. [For a binary modulus, this corresponds to a bit-wise
- complement of the binary representation of the value of the operand.]
-
- 6 The operator not that applies to a one-dimensional array of boolean
- components yields a one-dimensional boolean array with the same bounds; each
- component of the result is obtained by logical negation of the corresponding
- component of the operand (that is, the component that has the same index
- value). {Range_Check [partial]} {check, language-defined (Range_Check)}
- {Constraint_Error (raised by failure of run-time check)} A check is made that
- each component of the result belongs to the component subtype; the exception
- Constraint_Error is raised if this check fails.
-
- 6.a Discussion: The check against the component subtype is per
- AI-00535.
-
- 7 {exponentiation operator} {operator (exponentiation)} {** operator}
- {operator (**)} The highest precedence exponentiation operator ** is
- predefined for every specific integer type T with the following
- specification: {94-4693.v}
-
- 8 function "**"(Left : T; Right : Natural) return T
-
- 9 Exponentiation is also predefined for every specific floating point type
- as well as root_real, with the following specification (where T is root_real
- or the floating point type):
-
- 10 function "**"(Left : T; Right : Integer'Base) return T
-
- 11 {exponent} The right operand of an exponentiation is the exponent. The
- expression X**N with the value of the exponent N positive is equivalent to
- the expression X*X*...X (with N-1 multiplications) except that the
- multiplications are associated in an arbitrary order. With N equal to zero,
- the result is one. With the value of N negative [(only defined for a
- floating point operand)], the result is the reciprocal of the result using
- the absolute value of N as the exponent.
-
- 11.a Ramification: The language does not specify the order of
- association of the multiplications inherent in an exponentiation.
- For a floating point type, the accuracy of the result might depend on
- the particular association order chosen.
-
-
- Implementation Permissions
-
- 12 {Constraint_Error (raised by failure of run-time check)} The
- implementation of exponentiation for the case of a negative exponent is
- allowed to raise Constraint_Error if the intermediate result of the repeated
- multiplications is outside the safe range of the type, even though the final
- result (after taking the reciprocal) would not be. (The best machine
- approximation to the final result in this case would generally be 0.0.)
-
-
- NOTES
- 13 (19) {Range_Check [partial]} {check, language-defined (Range_Check)} As
- implied by the specification given above for exponentiation of an
- integer type, a check is made that the exponent is not negative.
- {Constraint_Error (raised by failure of run-time check)} Constraint_
- Error is raised if this check fails.
-
-
- Wording Changes From Ada 83
-
- 13.a We now show the specification for "**" for integer types with
- a parameter subtype of Natural rather than Integer for the exponent.
- This reflects the fact that Constraint_Error is raised if a negative
- value is provided for the exponent.
-
-
-
- 4.6 Type Conversions
-
- 1 [Explicit type conversions, both value conversions and view conversions,
- are allowed between closely related types as defined below. This clause also
- defines rules for value and view conversions to a particular subtype of a
- type, both explicit ones and those implicit in other constructs. {subtype
- conversion: see type conversion} {type conversion} {conversion} {cast: see
- type conversion} ]{subtype conversion: see also implicit subtype conversion}
- {type conversion, implicit: see implicit subtype conversion}
- Syntax
-
- 2 type_conversion ::=
- subtype_mark(expression)
- | subtype_mark(name)
-
-
- 3 {target subtype (of a type_conversion)} The target subtype of a type_
- conversion is the subtype denoted by the subtype_mark. {operand (of a type_
- conversion)} The operand of a type_conversion is the expression or name
- within the parentheses; {operand type (of a type_conversion)} its type is the
- operand type.
-
- 4 {convertible} One type is convertible to a second type if a type_
- conversion with the first type as operand type and the second type as target
- type is legal according to the rules of this clause. Two types are
- convertible if each is convertible to the other.
-
- 4.a Ramification: Note that ``convertible'' is defined in terms of
- legality of the conversion. Whether the conversion would raise an
- exception at run time is irrelevant to this definition.
-
- 5 {view conversion} {conversion (view)} A type_conversion whose operand is
- the name of an object is called a view conversion if its target type is
- tagged, or if it appears as an actual parameter of mode out or in out; {value
- conversion} {conversion (value)} other type_conversions are called value
- conversions. {super: see view conversion}
-
- 5.a Ramification: A view conversion to a tagged type can appear in
- any context that requires an object name, including in an object
- renaming, the prefix of a selected_component, and if the operand is a
- variable, on the left side of an assignment_statement. View
- conversions to other types only occur as actual parameters. Allowing
- view conversions of untagged types in all contexts seemed to incur an
- undue implementation burden.
-
-
- Name Resolution Rules
-
- 6 {expected type [type_conversion operand]} The operand of a type_
- conversion is expected to be of any type.
-
- 6.a Discussion: This replaces the "must be determinable" wording
- of Ada 83. This is equivalent to (but hopefully more intuitive than)
- saying that the operand of a type_conversion is a ``complete
- context.''
-
- 7 The operand of a view conversion is interpreted only as a name; the
- operand of a value conversion is interpreted as an expression.
-
- 7.a Reason: This formally resolves the syntactic ambiguity between
- the two forms of type_conversion, not that it really matters.
-
-
- Legality Rules
-
- 8 {type conversion (numeric)} {conversion (numeric)} If the target type is
- a numeric type, then the operand type shall be a numeric type.
-
- 9 {type conversion (array)} {conversion (array)} If the target type is an
- array type, then the operand type shall be an array type. Further:
-
- 10 The types shall have the same dimensionality;
-
- 11 Corresponding index types shall be convertible; and {convertible
- [required]}
-
- 12 The component subtypes shall statically match. {statically
- matching [required]}
-
- 13 {type conversion (access)} {conversion (access)} If the target type is a
- general access type, then the operand type shall be an access-to-object type.
- Further:
-
- 13.a Discussion: The Legality Rules and Dynamic Semantics are
- worded so that a type_conversion T(X) (where T is an access type) is
- (almost) equivalent to the attribute_reference X.all'Access, where
- the result is of type T. The type_conversion accepts a null value,
- whereas the attribute_reference would raise Constraint_Error.
-
- 14 If the target type is an access-to-variable type, then the
- operand type shall be an access-to-variable type;
-
- 14.a Ramification: If the target type is an access-to-constant type,
- then the operand type can be access-to-constant or
- access-to-variable.
-
- 15 If the target designated type is tagged, then the operand
- designated type shall be convertible to the target designated
- type; {convertible [required]}
-
- 16 If the target designated type is not tagged, then the designated
- types shall be the same, and either the designated subtypes shall
- statically match or the target designated subtype shall be
- discriminated and unconstrained; and {statically matching
- [required]}
-
- 16.a Reason: These rules are designed to ensure that aliased array
- objects only need "dope" if their nominal subtype is
- unconstrained, but they can always have dope if required by the
- run-time model (since no sliding is permitted as part of access
- type conversion). By contrast, aliased discriminated objects
- will always need their discriminants stored with them, even if
- nominally constrained. (Here, we are assuming an implementation
- that represents an access value as a single pointer.)
-
- 17 {accessibility rule [type conversion]} The accessibility level of
- the operand type shall not be statically deeper than that of the
- target type. {94-4715.a} {generic contract issue [partial]} In
- addition to the places where Legality Rules normally apply (see
- 12.3), this rule applies also in the private part of an instance
- of a generic unit.
-
- 17.a Ramification: The access parameter case is handled by a
- run-time check. Run-time checks are also done in instance
- bodies.
-
- 18 {type conversion (access)} {conversion (access)} If the target type is
- an access-to-subprogram type, then the operand type shall be an
- access-to-subprogram type. Further:
-
- 19 The designated profiles shall be subtype-conformant. {subtype
- conformance (required)}
-
- 20 {accessibility rule [type conversion]} The accessibility level of
- the operand type shall not be statically deeper than that of the
- target type. {94-4715.a} {generic contract issue [partial]} In
- addition to the places where Legality Rules normally apply (see
- 12.3), this rule applies also in the private part of an instance
- of a generic unit. If the operand type is declared within a
- generic body, the target type shall be declared within the
- generic body. {94-4692.a} {94-4702.a} {94-4706.a} {94-4708.a}
-
- 20.a Reason: The reason it is illegal to convert from an
- access-to-subprogram type declared in a generic body to one
- declared outside that body is that in an implementation that
- shares generic bodies, procedures declared inside the generic
- need to have a different calling convention -- they need an
- extra parameter pointing to the data declared in the current
- instance. For procedures declared in the spec, that's OK,
- because the compiler can know about them at compile time of the
- instantiation.
-
- 21 {type conversion (enumeration)} {conversion (enumeration)} {type
- conversion (composite (non-array))} {conversion (composite (non-array))} If
- the target type is not included in any of the above four cases, there shall
- be a type that is an ancestor of both the target type and the operand type.
- Further, if the target type is tagged, then either:
-
- 22 The operand type shall be covered by or descended from the target
- type; or
-
- 22.a Ramification: This is a conversion toward the root, which is
- always safe.
-
- 23 The operand type shall be a class-wide type that covers the
- target type.
-
- 23.a Ramification: This is a conversion of a class-wide type toward
- the leaves, which requires a tag check. See Dynamic Semantics.
-
- 23.b These two rules imply that a conversion from a parent type to a
- type extension is not permitted, as this would require
- specifying the values for additional components, in general, and
- changing the tag. An extension_aggregate has to be used
- instead, constructing a new value, rather than converting an
- existing value. However, a conversion from the class-wide type
- rooted at the parent type is permitted; such a conversion just
- verifies that the operand's tag is a descendant of the target.
-
- 24 In a view conversion for an untagged type, the target type shall be
- convertible (back) to the operand type.
-
- 24.a Reason: Untagged view conversions appear only as [in] out
- parameters. Hence, the reverse conversion must be legal as well.
- The forward conversion must be legal even if an out parameter,
- because actual parameters of an access type are always copied in
- anyway.
-
-
- Static Semantics
-
- 25 A type_conversion that is a value conversion denotes the value that is
- the result of converting the value of the operand to the target subtype.
-
- 26 A type_conversion that is a view conversion denotes a view of the object
- denoted by the operand. This view is a variable of the target type if the
- operand denotes a variable; otherwise it is a constant of the target type.
-
- 27 {nominal subtype [associated with a type_conversion]} The nominal
- subtype of a type_conversion is its target subtype.
-
-
- Dynamic Semantics
-
- 28 {evaluation [value conversion]} {corresponding value (of the target type
- of a conversion)} {conversion} For the evaluation of a type_conversion that
- is a value conversion, the operand is evaluated, and then the value of the
- operand is converted to a corresponding value of the target type, if any.
- {Range_Check [partial]} {check, language-defined (Range_Check)} {Constraint_
- Error (raised by failure of run-time check)} If there is no value of the
- target type that corresponds to the operand value, Constraint_Error is
- raised[; this can only happen on conversion to a modular type, and only when
- the operand value is outside the base range of the modular type.] Additional
- rules follow: {94-4667.l}
-
- 29 {type conversion (numeric)} {conversion (numeric)} Numeric Type
- Conversion
-
- 30 If the target and the operand types are both integer
- types, then the result is the value of the target type
- that corresponds to the same mathematical integer as the
- operand.
-
- 31 If the target type is a decimal fixed point type, then the
- result is truncated (toward 0) if the value of the operand
- is not a multiple of the small of the target type.
-
- 32 {accuracy} If the target type is some other real type,
- then the result is within the accuracy of the target type
- (see G.2, ``Numeric Performance Requirements'', for
- implementations that support the Numerics Annex).
- {94-4481.a}
-
- 32.a Discussion: An integer type might have more bits of precision
- than a real type, so on conversion (of a large integer), some
- precision might be lost.
-
- 33 If the target type is an integer type and the operand type
- is real, the result is rounded to the nearest integer
- (away from zero if exactly halfway between two integers).
-
- 33.a Discussion: This was implementation defined in Ada 83. There
- seems no reason to preserve the nonportability in Ada 9X.
- Round-away-from-zero is the conventional definition of rounding,
- and standard Fortran and COBOL both specify rounding away from
- zero, so for interoperability, it seems important to pick this.
- This is also the most easily ``undone'' by hand.
- Round-to-nearest-even is an alternative, but that is quite
- complicated if not supported by the hardware. In any case, this
- operation is not expected to be part of an inner loop, so
- predictability and portability are judged most important. We
- anticipate that a floating point attribute function Unbiased_
- Rounding will be provided for those applications that require
- round-to-nearest-even. ``Deterministic'' rounding is required
- for static conversions to integer as well. See 4.9.
-
- 34 {type conversion (enumeration)} {conversion (enumeration)}
- Enumeration Type Conversion
-
- 35 The result is the value of the target type with the same
- position number as that of the operand value.
-
- 36 {type conversion (array)} {conversion (array)} Array Type
- Conversion
-
- 37 {Length_Check [partial]} {check, language-defined (Length_
- Check)} If the target subtype is a constrained array
- subtype, then a check is made that the length of each
- dimension of the value of the operand equals the length of
- the corresponding dimension of the target subtype. The
- bounds of the result are those of the target subtype.
-
- 38 {Range_Check [partial]} {check, language-defined (Range_
- Check)} If the target subtype is an unconstrained array
- subtype, then the bounds of the result are obtained by
- converting each bound of the value of the operand to the
- corresponding index type of the target type. {implicit
- subtype conversion [array bounds]} For each nonnull index
- range, a check is made that the bounds of the range belong
- to the corresponding index subtype.
-
- 38.a Discussion: Only nonnull index ranges are checked, per
- AI-00313.
-
- 39 In either array case, the value of each component of the
- result is that of the matching component of the operand
- value (see 4.5.2).
-
- 39.a Ramification: This applies whether or not the component is
- initialized.
-
- 40 {type conversion (composite (non-array))} {conversion (composite
- (non-array))} Composite (Non-Array) Type Conversion
-
- 41 The value of each nondiscriminant component of the result
- is that of the matching component of the operand value.
-
- 41.a Ramification: This applies whether or not the component is
- initialized.
-
- 42 [The tag of the result is that of the operand.] {Tag_
- Check [partial]} {check, language-defined (Tag_Check)} If
- the operand type is class-wide, a check is made that the
- tag of the operand identifies a (specific) type that is
- covered by or descended from the target type.
-
- 42.a Ramification: This check is certain to succeed if the operand
- type is itself covered by or descended from the target type.
-
- 42.b Proof: The fact that a type_conversion preserves the tag is
- stated officially in 3.9, ``Tagged Types and Type Extensions''
-
- 43 For each discriminant of the target type that corresponds
- to a discriminant of the operand type, its value is that
- of the corresponding discriminant of the operand value;
- {Discriminant_Check [partial]} {check, language-defined
- (Discriminant_Check)} if it corresponds to more than one
- discriminant of the operand type, a check is made that all
- these discriminants are equal in the operand value.
-
- 44 For each discriminant of the target type that corresponds
- to a discriminant that is specified by the derived_type_
- definition for some ancestor of the operand type (or if
- class-wide, some ancestor of the specific type identified
- by the tag of the operand), its value in the result is
- that specified by the derived_type_definition.
-
- 44.a Ramification: It is a ramification of the rules for the
- discriminants of derived types that each discriminant of the
- result is covered either by this paragraph or the previous one.
- See 3.7.
-
- 45 {Discriminant_Check [partial]} {check, language-defined
- (Discriminant_Check)} For each discriminant of the operand
- type that corresponds to a discriminant that is specified
- by the derived_type_definition for some ancestor of the
- target type, a check is made that in the operand value it
- equals the value specified for it.
-
- 46 {Range_Check [partial]} {check, language-defined (Range_
- Check)} For each discriminant of the result, a check is
- made that its value belongs to its subtype.
-
- 47 {type conversion (access)} {conversion (access)} Access Type
- Conversion
-
- 48 {Accessibility_Check [partial]} {check, language-defined
- (Accessibility_Check)} For an access-to-object type, a
- check is made that the accessibility level of the operand
- type is not deeper than that of the target type.
- {94-4715.a}
-
- 48.a Ramification: This check is needed for operands that are access
- parameters and in instance bodies.
-
- 48.b Note that this check can never fail for the implicit conversion
- to the anonymous type of an access parameter that is done when
- calling a subprogram with an access parameter. {94-4715.a}
-
- 49 {Access_Check [partial]} {check, language-defined (Access_
- Check)} If the target type is an anonymous access type, a
- check is made that the value of the operand is not null;
- if the target is not an anonymous access type, then the
- result is null if the operand value is null.
-
- 49.a Ramification: A conversion to an anonymous access type happens
- implicitly as part of initializing an access discriminant or
- access parameter.
-
- 49.b Reason: As explained in 3.10, ``Access Types'', it is important
- that a value of an anonymous access type can never be null.
-
- 50 If the operand value is not null, then the result
- designates the same object (or subprogram) as is
- designated by the operand value, but viewed as being of
- the target designated subtype (or profile); any checks
- associated with evaluating a conversion to the target
- designated subtype are performed.
-
- 50.a Ramification: The checks are certain to succeed if the target
- and operand designated subtypes statically match.
-
- 51 {Range_Check [partial]} {check, language-defined (Range_Check)}
- {Discriminant_Check [partial]} {check, language-defined (Discriminant_Check)}
- {Index_Check [partial]} {check, language-defined (Index_Check)} After
- conversion of the value to the target type, if the target subtype is
- constrained, a check is performed that the value satisfies this constraint.
-
- 51.a Ramification: The above check is a Range_Check for scalar
- subtypes, a Discriminant_Check or Index_Check for access subtypes,
- and a Discriminant_Check for discriminated subtypes. The Length_
- Check for an array conversion is performed as part of the conversion
- to the target type.
-
- 52 {evaluation [view conversion]} For the evaluation of a view conversion,
- the operand name is evaluated, and a new view of the object denoted by the
- operand is created, whose type is the target type; {Length_Check [partial]}
- {check, language-defined (Length_Check)} {Tag_Check [partial]} {check,
- language-defined (Tag_Check)} {Discriminant_Check [partial]} {check,
- language-defined (Discriminant_Check)} if the target type is composite,
- checks are performed as above for a value conversion.
-
- 53 The properties of this new view are as follows:
-
- 54 If the target type is composite, the bounds or discriminants (if
- any) of the view are as defined above for a value conversion;
- each nondiscriminant component of the view denotes the matching
- component of the operand object; the subtype of the view is
- constrained if either the target subtype or the operand object is
- constrained, or if the operand type is a descendant of the target
- type, and has discriminants that were not inherited from the
- target type;
-
- 55 If the target type is tagged, then an assignment to the view
- assigns to the corresponding part of the object denoted by the
- operand; otherwise, an assignment to the view assigns to the
- object, after converting the assigned value to the subtype of the
- object (which might raise Constraint_Error); {implicit subtype
- conversion [assignment to view conversion]}
-
- 56 Reading the value of the view yields the result of converting the
- value of the operand object to the target subtype (which might
- raise Constraint_Error), except if the object is of an access
- type and the view conversion is passed as an out parameter; in
- this latter case, the value of the operand object is used to
- initialize the formal parameter without checking against any
- constraint of the target subtype (see 6.4.1). {implicit subtype
- conversion [reading a view conversion]}
-
- 56.a Reason: This ensures that even an out parameter of an access
- type is initialized reasonably.
-
- 57 {Program_Error (raised by failure of run-time check)} {Constraint_Error
- (raised by failure of run-time check)} If an Accessibility_Check fails,
- Program_Error is raised. Any other check associated with a conversion raises
- Constraint_Error if it fails.
-
- 58 Conversion to a type is the same as conversion to an unconstrained
- subtype of the type.
-
- 58.a Reason: This definition is needed because the semantics of
- various constructs involves converting to a type, whereas an explicit
- type_conversion actually converts to a subtype. For example, the
- evaluation of a range is defined to convert the values of the
- expressions to the type of the range.
-
- 58.b Ramification: A conversion to a scalar type, or,
- equivalently, to an unconstrained scalar subtype, can raise
- Constraint_Error if the value is outside the base range of the type.
-
-
- NOTES
- 59 (20) {implicit subtype conversion [distributed]} In addition to explicit
- type_conversions, type conversions are performed implicitly in
- situations where the expected type and the actual type of a construct
- differ, as is permitted by the type resolution rules (see 8.6). For
- example, an integer literal is of the type universal_integer, and is
- implicitly converted when assigned to a target of some specific integer
- type. Similarly, an actual parameter of a specific tagged type is
- implicitly converted when the corresponding formal parameter is of a
- class-wide type.
-
- 60 {implicit subtype conversion [distributed]} {Constraint_Error
- (raised by failure of run-time check)} Even when the expected and actual
- types are the same, implicit subtype conversions are performed to adjust
- the array bounds (if any) of an operand to match the desired target
- subtype, or to raise Constraint_Error if the (possibly adjusted) value
- does not satisfy the constraints of the target subtype.
-
- 61 (21) A ramification of the overload resolution rules is that the operand
- of an (explicit) type_conversion cannot be the literal null, an
- allocator, an aggregate, a string_literal, a character_literal, or an
- attribute_reference for an Access or Unchecked_Access attribute.
- Similarly, such an expression enclosed by parentheses is not allowed. A
- qualified_expression (see 4.7) can be used instead of such a type_
- conversion.
-
- 62 (22) The constraint of the target subtype has no effect for a type_
- conversion of an elementary type passed as an out parameter. Hence, it
- is recommended that the first subtype be specified as the target to
- minimize confusion (a similar recommendation applies to renaming and
- generic formal in out objects).
-
-
- Examples
-
- 63 Examples of numeric type conversion:
-
- 64 Real(2*J) -- value is converted to floating point
- Integer(1.6) -- value is 2
- Integer(-0.4) -- value is 0
-
- 65 Example of conversion between derived types:
-
- 66 type A_Form is new B_Form;
-
- 67 X : A_Form;
- Y : B_Form;
-
- 68 X := A_Form(Y);
- Y := B_Form(X); -- the reverse conversion
-
- 69 Examples of conversions between array types:
-
- 70 type Sequence is array (Integer range <>) of Integer;
- subtype Dozen is Sequence(1 .. 12);
- Ledger : array(1 .. 100) of Integer;
-
- 71 Sequence(Ledger) -- bounds are those of Ledger
- Sequence(Ledger(31 .. 42)) -- bounds are 31 and 42
- Dozen(Ledger(31 .. 42)) -- bounds are those of Dozen
-
-
- Incompatibilities With Ada 83
-
- 71.a {incompatibilities with Ada 83} A character_literal is not
- allowed as the operand of a type_conversion, since there are now two
- character types in package Standard.
-
- 71.b The component subtypes have to statically match in an array
- conversion, rather than being checked for matching constraints at run
- time.
-
- 71.c Because sliding of array bounds is now provided for operations
- where it was not in Ada 83, programs that used to raise Constraint_
- Error might now continue executing and produce a reasonable result.
- This is likely to fix more bugs than it creates.
-
- Extensions to Ada 83
-
- 71.d {extensions to Ada 83} A type_conversion is considered the
- name of an object in certain circumstances (such a type_conversion is
- called a view conversion). In particular, as in Ada 83, a type_
- conversion can appear as an in out or out actual parameter. In
- addition, if the target type is tagged and the operand is the name of
- an object, then so is the type_conversion, and it can be used as the
- prefix to a selected_component, in an object_renaming_declaration,
- etc.
-
- 71.e We no longer require type-mark conformance between a parameter
- of the form of a type conversion, and the corresponding formal
- parameter. This had caused some problems for inherited subprograms
- (since there isn't really a type-mark for converted formals), as well
- as for renamings, formal subprograms, etc. See AI-245, AI-318,
- AI-547.
-
- 71.f We now specify ``deterministic'' rounding from real to integer
- types when the value of the operand is exactly between two integers
- (rounding is away from zero in this case).
-
- 71.g ``Sliding'' of array bounds (which is part of conversion to an
- array subtype) is performed in more cases in Ada 9X than in Ada 83.
- Sliding is not performed on the operand of a membership test, nor on
- the operand of a qualified_expression. It wouldn't make sense on a
- membership test, and we wish to retain a connection between subtype
- membership and subtype qualification. In general, a subtype
- membership test returns True if and only if a corresponding subtype
- qualification succeeds without raising an exception. Other
- operations that take arrays perform sliding.
-
- Wording Changes From Ada 83
-
- 71.h We no longer explicitly list the kinds of things that are not
- allowed as the operand of a type_conversion, except in a NOTE.
-
- 71.i The rules in this clause subsume the rules for "parameters of
- the form of a type conversion," and have been generalized to cover
- the use of a type conversion as a name.
-
-
-
- 4.7 Qualified Expressions
-
- 1 [A qualified_expression is used to state explicitly the type, and to
- verify the subtype, of an operand that is either an expression or an
- aggregate. {type conversion: see also qualified_expression} ]
-
-
- Syntax
-
- 2 qualified_expression ::=
- subtype_mark'(expression) | subtype_mark'aggregate
-
-
- Name Resolution Rules
-
- 3 {operand [of a qualified_expression]} The operand (the expression or
- aggregate) shall resolve to be of the type determined by the subtype_mark, or
- a universal type that covers it.
-
-
- Dynamic Semantics
-
- 4 {evaluation [qualified_expression]} {Range_Check [partial]} {check,
- language-defined (Range_Check)} {Discriminant_Check [partial]} {check,
- language-defined (Discriminant_Check)} {Index_Check [partial]} {check,
- language-defined (Index_Check)} The evaluation of a qualified_expression
- evaluates the operand (and if of a universal type, converts it to the type
- determined by the subtype_mark) and checks that its value belongs to the
- subtype denoted by the subtype_mark. {implicit subtype conversion
- [qualified_expression]} {Constraint_Error (raised by failure of run-time
- check)} The exception Constraint_Error is raised if this check fails.
-
- 4.a Ramification: This is one of the few contexts in Ada 9X where
- implicit subtype conversion is not performed prior to a constraint
- check, and hence no ``sliding'' of array bounds is provided.
-
- 4.b Reason: Implicit subtype conversion is not provided because a
- qualified_expression with a constrained target subtype is essentially
- an assertion about the subtype of the operand, rather than a request
- for conversion. An explicit type_conversion can be used rather than
- a qualified_expression if subtype conversion is desired.
-
-
- NOTES
- 5 (23) When a given context does not uniquely identify an expected type, a
- qualified_expression can be used to do so. In particular, if an
- overloaded name or aggregate is passed to an overloaded subprogram, it
- might be necessary to qualify the operand to resolve its type.
-
-
- Examples
-
- 6 Examples of disambiguating expressions using qualification:
-
- 7 type Mask is (Fix, Dec, Exp, Signif);
- type Code is (Fix, Cla, Dec, Tnz, Sub);
-
- 8 Print (Mask'(Dec)); -- Dec is of type Mask
- Print (Code'(Dec)); -- Dec is of type Code
-
- 9 for J in Code'(Fix) .. Code'(Dec) loop ... -- qualification needed for eith\
- er Fix or Dec
- for J in Code range Fix .. Dec loop ... -- qualification unnecessary
- for J in Code'(Fix) .. Dec loop ... -- qualification unnecessary for\
- Dec
-
- 10 Dozen'(1 | 3 | 5 | 7 => 2, others => 0) -- see 4.6
-
-
-
- 4.8 Allocators
-
- 1 [The evaluation of an allocator creates an object and yields an access
- value that designates the object. {new: see allocator} {malloc: see
- allocator} {heap management: see also alligator} ]
-
-
- Syntax
-
- 2 allocator ::=
- new subtype_indication | new qualified_expression
-
-
- Name Resolution Rules
-
- 3 {expected type [allocator]} The expected type for an allocator shall be a
- single access-to-object type whose designated type covers the type determined
- by the subtype_mark of the subtype_indication or qualified_expression.
-
- 3.a Discussion: See 8.6, ``The Context of Overload Resolution''
- for the meaning of ``shall be a single ... type whose ...''
-
-
- Legality Rules
-
- 4 {initialized allocator} An initialized allocator is an allocator with a
- qualified_expression. {uninitialized allocator} An uninitialized allocator
- is one with a subtype_indication. In the subtype_indication of an
- uninitialized allocator, a constraint is permitted only if the subtype_mark
- denotes an [unconstrained] composite subtype; if there is no constraint, then
- the subtype_mark shall denote a definite subtype. {94-4759.a} {constructor:
- see initialized alligator}
-
- 4.a Ramification: For example, ... new S'Class ... (with no
- initialization expression) is illegal, but ... new S'Class'(X) ... is
- legal, and takes its tag and constraints from the initial value
- X. (Note that the former case cannot have a constraint.)
-
- 5 If the type of the allocator is an access-to-constant type, the allocator
- shall be an initialized allocator. If the designated type is limited, the
- allocator shall be an uninitialized allocator.
-
- 5.a Ramification: For an access-to-constant type whose designated
- type is limited, allocators are illegal. The Access attribute is
- legal for such a type, however.
-
-
- Static Semantics
-
- 6 If the designated type of the type of the allocator is elementary, then
- the subtype of the created object is the designated subtype. If the
- designated type is composite, then the created object is always constrained;
- if the designated subtype is constrained, then it provides the constraint of
- the created object; otherwise, the object is constrained by its initial value
- [(even if the designated subtype is unconstrained with defaults)].
- {constrained by its initial value [partial]}
-
- 6.a Discussion: See AI-00331.
-
- 6.b Reason: All objects created by an allocator are aliased, and
- all aliased composite objects need to be constrained so that access
- subtypes work reasonably.
-
-
- Dynamic Semantics
-
- 7 {evaluation [allocator]} For the evaluation of an allocator, the
- elaboration of the subtype_indication or the evaluation of the qualified_
- expression is performed first. {evaluation [initialized allocator]}
- {assignment operation (during evaluation of an initialized allocator)} For
- the evaluation of an initialized allocator, an object of the designated type
- is created and the value of the qualified_expression is converted to the
- designated subtype and assigned to the object. {implicit subtype conversion
- [initialization expression of allocator]}
-
- 7.a Ramification: The conversion might raise Constraint_Error.
-
- 8 {evaluation [uninitialized allocator]} For the evaluation of an
- uninitialized allocator:
-
- 9 {assignment operation (during evaluation of an uninitialized
- allocator)} If the designated type is elementary, an object of
- the designated subtype is created and any implicit initial value
- is assigned;
-
- 10 {assignment operation (during evaluation of an uninitialized
- allocator)} If the designated type is composite, an object of the
- designated type is created with tag, if any, determined by the
- subtype_mark of the subtype_indication; any per-object con-
- straints on subcomponents are elaborated and any implicit initial
- values for the subcomponents of the object are obtained as
- determined by the subtype_indication and assigned to the
- corresponding subcomponents. {Index_Check [partial]} {check,
- language-defined (Index_Check)} {Discriminant_Check [partial]}
- {check, language-defined (Discriminant_Check)} A check is made
- that the value of the object belongs to the designated subtype.
- {Constraint_Error (raised by failure of run-time check)}
- Constraint_Error is raised if this check fails. This check and
- the initialization of the object are performed in an arbitrary
- order.
-
- 10.a Discussion: AI-00150.
-
- 11 [If the created object contains any tasks, they are activated (see
- 9.2).] Finally, an access value that designates the created object is
- returned.
-
-
- NOTES
- 12 (24) Allocators cannot create objects of an abstract type. See 3.9.3.
-
- 13 (25) If any part of the created object is controlled, the initialization
- includes calls on corresponding Initialize or Adjust procedures. See
- 7.6.
-
- 14 (26) As explained in 13.11, ``Storage Management'', the storage for an
- object allocated by an allocator comes from a storage pool (possibly
- user defined). {Storage_Error (raised by failure of run-time check)}
- The exception Storage_Error is raised by an allocator if there is not
- enough storage. Instances of Unchecked_Deallocation may be used to
- explicitly reclaim storage.
-
- 15 (27) Implementations are permitted, but not required, to provide garbage
- collection (see 13.11.3).
-
- 15.a Ramification: Note that in an allocator, the exception Constraint_
- Error can be raised by the evaluation of the qualified_expression, by
- the elaboration of the subtype_indication, or by the initialization.
-
- 15.b Discussion: By default, the implementation provides the storage
- pool. The user may exercise more control over storage management by
- associating a user-defined pool with an access type.
-
-
- Examples
-
- 16 Examples of allocators:
-
- 17 new Cell'(0, null, null) -- initialized explicitly\
- , see 3.10.1
- new Cell'(Value => 0, Succ => null, Pred => null) -- initialized explicitly
- new Cell -- not initialized
-
- 18 new Matrix(1 .. 10, 1 .. 20) -- the bounds only are gi\
- ven
- new Matrix'(1 .. 10 => (1 .. 20 => 0.0)) -- initialized explicitly
-
- 19 new Buffer(100) -- the discriminant only \
- is given
- new Buffer'(Size => 80, Pos => 0, Value => (1 .. 80 => 'A')) -- initialized\
- explicitly
-
- 20 Expr_Ptr'(new Literal) -- allocator for access-to-cl\
- ass-wide type, see 3.9.1
- Expr_Ptr'(new Literal'(Expression with 3.5)) -- initialized explicitly
-
-
- Incompatibilities With Ada 83
-
- 20.a {incompatibilities with Ada 83} The subtype_indication of an
- uninitialized allocator may not have an explicit constraint if the
- designated type is an access type. In Ada 83, this was permitted
- even though the constraint had no affect on the subtype of the
- created object.
-
- Extensions to Ada 83
-
- 20.b {extensions to Ada 83} Allocators creating objects of type T
- are now overloaded on access types designating T'Class and all
- class-wide types that cover T.
-
- 20.c Implicit array subtype conversion (sliding) is now performed
- as part of an initialized allocator.
- Wording Changes From Ada 83
-
- 20.d We have used a new organization, inspired by the ACID
- document, that makes it clearer what is the subtype of the created
- object, and what subtype conversions take place.
-
- 20.e Discussion of storage management issues, such as garbage
- collection and the raising of Storage_Error, has been moved to 13.11,
- ``Storage Management''.
-
-
-
- 4.9 Static Expressions and Static Subtypes
-
- 1 Certain expressions of a scalar or string type are defined to be static.
- Similarly, certain discrete ranges are defined to be static, and certain
- scalar and string subtypes are defined to be static subtypes. [{static}
- Static means determinable at compile time, using the declared properties or
- values of the program entities.] {constant: see also static}
-
- 1.a Discussion: As opposed to more elaborate data flow analysis,
- etc.
-
-
- Language Design Principles
-
- 1.b For an expression to be static, it has to be calculable at
- compile time.
-
- 1.c Only scalar and string expressions are static.
-
- 1.d To be static, an expression cannot have any nonscalar,
- nonstring subexpressions (though it can have nonscalar constituent
- names). A static scalar expression cannot have any nonscalar
- subexpressions. There is one exception -- a membership test for a
- string subtype can be static, and the result is scalar, even though a
- subexpression is nonscalar. {94-4679.a} {94-4684.a} {94-4687.a}
-
- 1.e The rules for evaluating static expressions are designed to
- maximize portability of static calculations.
- 2 {static (expression)} A static expression is [a scalar or string
- expression that is] one of the following: {94-4679.a} {94-4684.a}
- {94-4687.a} {94-4738.a} {94-4926.a} {94-4929.a} {94-4950.a}
-
- 3 a numeric_literal;
-
- 3.a Ramification: A numeric_literal is always a static expression,
- even if its expected type is not that of a static subtype.
- However, if its value is explicitly converted to, or qualified
- by, a nonstatic subtype, the resulting expression is nonstatic.
-
- 4 a string_literal of a static string subtype;
-
- 4.a Ramification: That is, the constrained subtype defined by the
- index range of the string is static. Note that elementary
- values don't generally have subtypes, while composite values do
- (since the bounds or discriminants are inherent in the value).
-
- 5 a name that denotes the declaration of a named number or a static
- constant;
-
- 5.a Ramification: Note that enumeration literals are covered by the
- function_call case.
-
- 6 a function_call whose function_name or function_prefix statically
- denotes a static function, and whose actual parameters, if any
- (whether given explicitly or by default), are all static
- expressions;
-
- 6.a Ramification: This includes uses of operators that are
- equivalent to function_calls.
-
- 7 an attribute_reference that denotes a scalar value, and whose
- prefix denotes a static scalar subtype; {94-4679.c} {94-4684.c}
-
- 7.a Ramification: Note that this does not include the case of an
- attribute that is a function; a reference to such an attribute
- is not even an expression. See above for function calls.
-
- 7.b An implementation may define the staticness and other properties
- of implementation-defined attributes.
-
- 8 an attribute_reference whose prefix statically denotes a
- statically constrained array object or array subtype, and whose
- attribute_designator is First, Last, or Length, with an optional
- dimension; {94-4968.a}
-
- 9 a type_conversion whose subtype_mark denotes a static scalar
- subtype, and whose operand is a static expression;
-
- 10 a qualified_expression whose subtype_mark denotes a static
- [(scalar or string)] subtype, and whose operand is a static
- expression; {94-4667.p}
-
- 10.a Ramification: This rules out the subtype_mark'aggregate case.
-
- 10.b Reason: Adding qualification to an expression shouldn't make it
- nonstatic, even for strings.
-
- 11 a membership test whose simple_expression is a static expression,
- and whose range is a static range or whose subtype_mark denotes a
- static [(scalar or string)] subtype;
-
- 11.a Reason: Clearly, we should allow membership tests in exactly
- the same cases where we allow qualified_expressions.
-
- 12 a short-circuit control form both of whose relations are static
- expressions;
-
- 13 a static expression enclosed in parentheses.
-
- 13.a Discussion: {static (value)} Informally, we talk about a
- static value. When we do, we mean a value specified by a static
- expression.
-
- 13.b Ramification: The language requires a static expression in a
- number_declaration, a numeric type definition, a discrete_choice
- (sometimes), certain representation items, an attribute_designator,
- and when specifying the value of a discriminant governing a variant_
- part in a record_aggregate or extension_aggregate.
-
- 14 {statically (denote)} A name statically denotes an entity if it denotes
- the entity and:
-
- 15 It is a direct_name, expanded name, or character_literal, and it
- denotes a declaration other than a renaming_declaration; or
-
- 16 It is an attribute_reference whose prefix statically denotes some
- entity; or
-
- 17 It denotes a renaming_declaration with a name that statically
- denotes the renamed entity.
-
- 17.a Ramification: Selected_components that are not expanded names
- and indexed_components do not statically denote things.
-
- 18 {static (function)} A static function is one of the following:
-
- 18.a Ramification: These are the functions whose calls can be
- static expressions.
-
- 19 a predefined operator whose parameter and result types are all
- scalar types none of which are descendants of formal scalar
- types;
-
- 20 a predefined concatenation operator whose result type is a string
- type; {94-4679.a} {94-4684.a} {94-4687.a} {94-4738.a}
-
- 21 an enumeration literal;
-
- 22 a language-defined attribute that is a function, if the prefix
- denotes a static scalar subtype, and if the parameter and result
- types are scalar.
-
- 23 In any case, a generic formal subprogram is not a static function.
-
- 24 {static (constant)} A static constant is a constant view declared by a
- full constant declaration or an object_renaming_declaration with a static
- nominal subtype, having a value defined by a static scalar expression or by a
- static string expression whose value has a length not exceeding the maximum
- length of a string_literal in the implementation.
-
- 24.a Ramification: A deferred constant is not static; the view
- introduced by the corresponding full constant declaration can be
- static.
-
- 24.b Reason: The reason for restricting the length of static
- string constants is so that compilers don't have to store giant
- strings in their symbol tables. Since most string constants will be
- initialized from string_literals, the length limit seems pretty
- natural. The reason for avoiding nonstring types is also to save
- symbol table space. We're trying to keep it cheap and simple (from
- the implementer's viewpoint), while still allowing, for example, the
- link name of a pragma Import to contain a concatenation.
-
- 24.c The length we're talking about is the maximum number of
- characters in the value represented by a string_literal, not the
- number of characters in the source representation; the quotes don't
- count. {94-4747.b} {94-4748.b} {94-4754.b}
-
- 25 {static (range)} A static range is a range whose bounds are static
- expressions, [or a range_attribute_reference that is equivalent to such a
- range.] {static (discrete_range)} A static discrete_range is one that is a
- static range or is a subtype_indication that defines a static scalar subtype.
- The base range of a scalar type is a static range, unless the type is a
- descendant of a formal scalar type.
-
- 26 {static (subtype)} A static subtype is either a static scalar subtype or
- a static string subtype. {static (scalar subtype)} A static scalar subtype
- is an unconstrained scalar subtype whose type is not a descendant of a formal
- scalar type, or a constrained scalar subtype formed by imposing a compatible
- static constraint on a static scalar subtype. {static (string subtype)} A
- static string subtype is an unconstrained string subtype whose index subtype
- and component subtype are static (and whose type is not a descendant of a
- formal array type), or a constrained string subtype formed by imposing a
- compatible static constraint on a static string subtype. {94-4539.a} In any
- case, the subtype of a generic formal object of mode in out, and the result
- subtype of a generic formal function, are not static.
- 26.a Ramification: String subtypes are the only composite subtypes
- that can be static.
-
- 26.b Reason: The part about generic formal objects of mode in out
- is necessary because the subtype of the formal is not required to
- have anything to do with the subtype of the actual. For example:
-
- 26.c subtype Int10 is Integer range 1..10;
-
- 26.d generic
- F : in out Int10;
- procedure G;
-
- 26.e procedure G is
- begin
- case F is
- when 1..10 => null;
- -- Illegal!
- end case;
- end G;
-
- 26.f X : Integer range 1..20;
- procedure I is new G(F => X); -- OK.
-
- 26.g The case_statement is illegal, because the subtype of F is not
- static, so the choices have to cover all values of Integer, not just
- those in the range 1..10. A similar issue arises for generic formal
- functions, now that function calls are object names.
-
- 27 {static (constraint)} The different kinds of static constraint are
- defined as follows:
-
- 28 A null constraint is always static;
-
- 29 {static (range constraint)} {static (digits constraint)} {static
- (delta constraint)} A scalar constraint is static if it has no
- range_constraint, or one with a static range;
-
- 30 {static (index constraint)} An index constraint is static if each
- discrete_range is static, and each index subtype of the
- corresponding array type is static;
-
- 31 {static (discriminant constraint)} A discriminant constraint is
- static if each expression of the constraint is static, and the
- subtype of each discriminant is static.
-
- 32 {statically (constrained)} A subtype is statically constrained if it is
- constrained, and its constraint is static. An object is statically
- constrained if its nominal subtype is statically constrained, or if it is a
- static string constant. {94-4776.c}
-
-
- Legality Rules
-
- 33 A static expression is evaluated at compile time except when it is part
- of the right operand of a static short-circuit control form whose value is
- determined by its left operand. This evaluation is performed exactly,
- without performing Overflow_Checks. For a static expression that is
- evaluated:
-
- 34 The expression is illegal if its evaluation fails a
- language-defined check other than Overflow_Check.
-
- 35 If the expression is not part of a larger static expression, then
- its value shall be within the base range of its expected type.
- Otherwise, the value may be arbitrarily large or small.
-
- 36 If the expression is of type universal_real and its expected type
- is a decimal fixed point type, then its value shall be a multiple
- of the small of the decimal type.
-
- 36.a Ramification: This means that a numeric_literal for a decimal
- type cannot have ``extra'' significant digits.
-
- 37 The last two restrictions above do not apply if the expected type is a
- descendant of a formal scalar type (or a corresponding actual type in an
- instance). {94-4926.a} {94-4929.a} {94-4950.a}
-
- 37.a Discussion: Values outside the base range are not permitted
- when crossing from the ``static'' domain to the ``dynamic'' domain.
- This rule is designed to enhance portability of programs containing
- static expressions. Note that this rule applies to the exact value,
- not the value after any rounding or truncation. (See below for the
- rounding and truncation requirements.)
-
- 37.b Short-circuit control forms are a special case:
-
- 37.c N: constant := 0.0;
- X: constant Boolean := (N = 0.0) or else (1.0/N > 0.5); -- Static.
-
- 37.d The declaration of X is legal, since the divide-by-zero part
- of the expression is not evaluated. X is a static constant equal to
- True.
-
- 37.e Reason: There is no requirement to recheck these rules in an
- instance; the base range check will generally be performed at run
- time anyway.
-
-
- Implementation Requirements
-
- 38 For a real static expression that is not part of a larger static
- expression, and whose expected type is not a descendant of a formal scalar
- type, the implementation shall round or truncate the value (according to the
- Machine_Rounds attribute of the expected type) to the nearest machine number
- of the expected type; if the value is exactly half-way between two machine
- numbers, any rounding shall be performed away from zero. If the expected
- type is a descendant of a formal scalar type, no special rounding or
- truncating is required -- normal accuracy rules apply (see Annex G).
-
- 38.a Reason: Discarding extended precision enhances portability by
- ensuring that the value of a static constant of a real type is always
- a machine number of the type. Deterministic rounding of exact halves
- also enhances portability.
-
- 38.b When the expected type is a descendant of a formal floating
- point type, extended precision (beyond that of the machine numbers)
- can be retained when evaluating a static expression, to ease code
- sharing for generic instantiations. For similar reasons, normal
- (nondeterministic) rounding or truncating rules apply for descendants
- of a formal fixed point type.
-
- 38.c Implementation Note: Note that the implementation of static
- expressions has to keep track of plus and minus zero for a type whose
- Signed_Zeros attribute is True. {94-4539.c}
-
- 38.d Note that the only values of a fixed point type are the
- multiples of the small, so a static conversion to a fixed-point type,
- or division by an integer, must do truncation to a multiple of small.
- It is not correct for the implementation to do all static
- calculations in infinite precision.
-
-
- NOTES
- 39 (28) An expression can be static even if it occurs in a context where
- staticness is not required.
-
- 39.a Ramification: For example:
-
- 39.b X : Float := Float'(1.0E+400) + 1.0 - Float'(1.0E+400);
-
- 39.c The expression is static, which means that the value of X must be
- exactly 1.0, independent of the accuracy or range of the run-time
- floating point implementation.
-
- 39.d The following kinds of expressions are never static: explicit_
- dereference, indexed_component, slice, null, aggregate, allocator.
-
- 40 (29) A static (or run-time) type_conversion from a real type to an
- integer type performs rounding. If the operand value is exactly
- half-way between two integers, the rounding is performed away from zero.
-
- 40.a Reason: We specify this for portability. The reason for not
- choosing round-to-nearest-even, for example, is that this method is
- easier to undo.
-
- 40.b Ramification: The attribute Truncation (see A.5.3) can be used to
- perform a (static) truncation prior to conversion, to prevent
- rounding.
-
- 40.c Implementation Note: The value of the literal
- 0E999999999999999999999999999999999999999999999 is zero. The
- implementation must take care to evaluate such literals properly.
- {94-5001.d} {94-5005.c}
-
-
- Examples
-
- 41 Examples of static expressions:
-
- 42 1 + 1 -- 2
- abs(-10)*3 -- 30
-
- 43 Kilo : constant := 1000;
- Mega : constant := Kilo*Kilo; -- 1_000_000
- Long : constant := Float'Digits*2;
-
- 44 Half_Pi : constant := Pi/2; -- see 3.3.2
- Deg_To_Rad : constant := Half_Pi/90;
- Rad_To_Deg : constant := 1.0/Deg_To_Rad; -- equivalent to 1.0/((3.14159_265\
- 36/2)/90)
-
-
- Extensions to Ada 83
-
- 44.a {extensions to Ada 83} The rules for static expressions and
- static subtypes are generalized to allow more kinds of
- compile-time-known expressions to be used where compile-time-known
- values are required, as follows:
-
- 44.b Membership tests and short-circuit control forms may
- appear in a static expression.
-
- 44.c The bounds and length of statically constrained array
- objects or subtypes are static.
-
- 44.d The Range attribute of a statically constrained array
- subtype or object gives a static range.
-
- 44.e A type_conversion is static if the subtype_mark denotes a
- static scalar subtype and the operand is a static
- expression.
-
- 44.f All numeric literals are now static, even if the expected
- type is a formal scalar type. This is useful in case_
- statements and variant_parts, which both now allow a
- value of a formal scalar type to control the selection,
- to ease conversion of a package into a generic package.
- Similarly, named array aggregates are also permitted for
- array types with an index type that is a formal scalar
- type.
-
- 44.g The rules for the evaluation of static expressions are revised
- to require exact evaluation at compile time, and force a machine
- number result when crossing from the static realm to the dynamic
- realm, to enhance portability and predictability. Exact evaluation
- is not required for descendants of a formal scalar type, to simplify
- generic code sharing and to avoid generic contract model problems.
-
- 44.h Static expressions are legal even if an intermediate in the
- expression goes outside the base range of the type. Therefore, the
- following will succeed in Ada 9X, whereas it might raise an exception
- in Ada 83:
-
- 44.i type Short_Int is range -32_768 .. 32_767;
- I : Short_Int := -32_768;
-
- 44.j This might raise an exception in Ada 83 because "32_768" is
- out of range, even though "-32_768" is not. In Ada 9X, this will
- always succeed.
-
- 44.k Certain expressions involving string operations (in particular
- concatenation and membership tests) are considered static in Ada 9X.
-
- 44.l The reason for this change is to simplify the rule requiring
- compile-time-known string expressions as the link name in an
- interfacing pragma, and to simplify the preelaborability rules.
-
- Incompatibilities With Ada 83
-
- 44.m {incompatibilities with Ada 83} An Ada 83 program that uses an
- out-of-range static value is illegal in Ada 9X, unless the expression
- is part of a larger static expression, or the expression is not
- evaluated due to being on the right-hand side of a short-circuit
- control form.
-
- Wording Changes From Ada 83
-
- 44.n This clause (and 4.5.5, ``Multiplying Operators'') subsumes
- the RM83 section on Universal Expressions.
-
- 44.o The existence of static string expressions necessitated
- changing the definition of static subtype to include string subtypes.
- Most occurrences of "static subtype" have been changed to "static
- scalar subtype", in order to preserve the effect of the Ada 83 rules.
- This has the added benefit of clarifying the difference between
- "static subtype" and "statically constrained subtype", which has been
- a source of confusion. In cases where we allow static string
- subtypes, we explicitly use phrases like "static string subtype" or
- "static (scalar or string) subtype", in order to clarify the meaning
- for those who have gotten used to the Ada 83 terminology.
-
- 44.p In Ada 83, an expression was considered nonstatic if it raised
- an exception. Thus, for example:
-
- 44.q Bad: constant := 1/0; -- Illegal!
-
- 44.r was illegal because 1/0 was not static. In Ada 9X, the above
- example is still illegal, but for a different reason: 1/0 is static,
- but there's a separate rule forbidding the exception raising.
-
-
-
- 4.9.1 Statically Matching Constraints and Subtypes
-
- Static Semantics
-
- 1 {statically matching (for constraints)} A constraint statically matches
- another constraint if both are null constraints, both are static and have
- equal corresponding bounds or discriminant values, or both are nonstatic and
- result from the same elaboration of a constraint of a subtype_indication or
- the same evaluation of a range of a discrete_subtype_definition.
-
- 2 {statically matching (for subtypes)} A subtype statically matches another
- subtype of the same type if they have statically matching constraints. Two
- anonymous access subtypes statically match if their designated subtypes
- statically match.
-
- 2.a Ramification: Statically matching constraints and subtypes are
- the basis for subtype conformance of profiles (see 6.3.1).
-
- 3 {statically matching (for ranges)} Two ranges of the same type statically
- match if both result from the same evaluation of a range, or if both are
- static and have equal corresponding bounds.
-
- 3.a Ramification: The notion of static matching of ranges is used
- in 12.5.3, ``Formal Array Types''; the index ranges of formal and
- actual constrained array subtypes have to statically match.
-
- 4 {statically compatible (for a constraint and a scalar subtype)} A
- constraint is statically compatible with a scalar subtype if it statically
- matches the constraint of the subtype, or if both are static and the
- constraint is compatible with the subtype. {statically compatible (for a
- constraint and an access or composite subtype)} A constraint is statically
- compatible with an access or composite subtype if it statically matches the
- constraint of the subtype, or if the subtype is unconstrained. {statically
- compatible (for two subtypes)} One subtype is statically compatible with a
- second subtype if the constraint of the first is statically compatible with
- the second subtype.
-
- 4.a Discussion: Static compatibility is required when constraining
- a parent subtype with a discriminant from a new discriminant_part.
- See 3.7. Static compatibility is also used in matching generic
- formal derived types.
-
- 4.b Note that statically compatible with a subtype does not imply
- compatible with a type. It is OK since the terms are used in
- different contexts.
-
-
- Wording Changes From Ada 83
-
- 4.c This subclause is new to Ada 9X.
-
-
-
- Section 5: Statements
-
-
- 1 [A statement defines an action to be performed upon its execution.]
-
- 2 [This section describes the general rules applicable to all statements.
- Some statements are discussed in later sections: Procedure_call_statements
- and return_statements are described in Section 6, ``Subprograms''. Entry_
- call_statements, requeue_statements, delay_statements, accept_statements,
- select_statements, and abort_statements are described in Section 9, ``Tasks
- and Synchronization''. Raise_statements are described in Section 11,
- ``Exceptions'', and code_statements in Section 13. The remaining forms of
- statements are presented in this section.]
-
-
- Wording Changes From Ada 83
-
- 2.a The description of return_statements has been moved to 6.5,
- ``Return Statements'', so that it is closer to the description of
- subprograms.
-
-
-
- 5.1 Simple and Compound Statements - Sequences of Statements
-
- 1 [A statement is either simple or compound. A simple_statement encloses
- no other statement. A compound_statement can enclose simple_statements and
- other compound_statements.]
-
-
- Syntax
-
- 2 sequence_of_statements ::= statement {statement}
-
- 3 statement ::=
- {label} simple_statement | {label} compound_statement
-
- 4 simple_statement ::= null_statement
- | assignment_statement | exit_statement
- | goto_statement | procedure_call_statement
- | return_statement | entry_call_statement
- | requeue_statement | delay_statement
- | abort_statement | raise_statement
- | code_statement
-
- 5 compound_statement ::=
- if_statement | case_statement
- | loop_statement | block_statement
- | accept_statement | select_statement
-
- 6 null_statement ::= null;
-
- 7 label ::= <<label_statement_identifier>>
-
- 8 statement_identifier ::= direct_name
-
- 9 The direct_name of a statement_identifier shall be an identifier (not
- an operator_symbol).
-
-
- Name Resolution Rules
-
- 10 The direct_name of a statement_identifier shall resolve to denote its
- corresponding implicit declaration (see below).
-
-
- Legality Rules
-
- 11 Distinct identifiers shall be used for all statement_identifiers that
- appear in the same body, including inner block_statements but excluding inner
- program units.
- Static Semantics
-
- 12 For each statement_identifier, there is an implicit declaration (with
- the specified identifier) at the end of the declarative_part of the innermost
- block_statement or body that encloses the statement_identifier. The implicit
- declarations occur in the same order as the statement_identifiers occur in
- the source text. If a usage name denotes such an implicit declaration, the
- entity it denotes is the label, loop_statement, or block_statement with the
- given statement_identifier.
-
- 12.a Reason: We talk in terms of individual statement_identifiers
- here rather than in terms of the corresponding statements, since a
- given statement may have multiple statement_identifiers.
-
- 12.b A block_statement that has no explicit declarative_part has an
- implicit empty declarative_part, so this rule can safely refer to the
- declarative_part of a block_statement.
-
- 12.c The scope of a declaration starts at the place of the
- declaration itself (see 8.2). In the case of a label, loop, or block
- name, it follows from this rule that the scope of the implicit
- declaration starts before the first explicit occurrence of the
- corresponding name, since this occurrence is either in a statement
- label, a loop_statement, a block_statement, or a goto_statement. An
- implicit declaration in a block_statement may hide a declaration
- given in an outer program unit or block_statement (according to the
- usual rules of hiding explained in 8.3).
-
- 12.d The syntax rule for label uses statement_identifier which is a
- direct_name (not a defining_identifier), because labels are
- implicitly declared. The same applies to loop and block names. In
- other words, the label itself is not the defining occurrence; the
- implicit declaration is.
-
- 12.e We cannot consider the label to be a defining occurrence. An
- example that can tell the difference is this:
-
- 12.f declare
- -- Label Foo is implicitly declared here.
- begin
- for Foo in ... loop
- ...
- <<Foo>> -- Illegal.
- ...
- end loop;
- end;
-
- 12.g The label in this example is hidden from itself by the loop
- parameter with the same name; the example is illegal. We considered
- creating a new syntactic category name, separate from direct_name and
- selector_name, for use in the case of statement labels. However,
- that would confuse the rules in Section 8, so we didn't do it.
-
-
- Dynamic Semantics
-
- 13 {execution [null_statement]} The execution of a null_statement has no
- effect.
-
- 14 {transfer of control} A transfer of control is the run-time action of an
- exit_statement, return_statement, goto_statement, or requeue_statement,
- selection of a terminate_alternative, raising of an exception, or an abort,
- which causes the next action performed to be one other than what would
- normally be expected from the other rules of the language. [As explained in
- 7.6.1, a transfer of control can cause the execution of constructs to be
- completed and then left, which may trigger finalization.]
-
- 15 {execution [sequence_of_statements]} The execution of a sequence_of_
- statements consists of the execution of the individual statements in
- succession until the sequence_ is completed.
-
- 15.a Ramification: It could be completed by reaching the end of
- it, or by a transfer of control.
-
-
- NOTES
- 16 (1) A statement_identifier that appears immediately within the
- declarative region of a named loop_statement or an accept_statement is
- nevertheless implicitly declared immediately within the declarative
- region of the innermost enclosing body or block_statement; in other
- words, the expanded name for a named statement is not affected by
- whether the statement occurs inside or outside a named loop or an
- accept_statement -- only nesting within block_statements is relevant to
- the form of its expanded name.
-
- 16.a Discussion: Each comment in the following example gives the
- expanded name associated with an entity declared in the task body:
-
- 16.b task body Compute is
- Sum : Integer := 0; -- Compute.Sum
- begin
- Outer: -- Compute.Outer
- for I in 1..10 loop -- Compute.Outer.I
- Blk: -- Compute.Blk
- declare
- Sum : Integer := 0; -- Compute.Blk.Sum
- begin
- accept Ent(I : out Integer; J : in Integer) do
- -- Compute.Ent.I, Comp\
- ute.Ent.J
- Compute.Ent.I := Compute.Outer.I;
- Inner: -- Compute.Blk.Inner
- for J in 1..10 loop
- -- Compute.Blk.Inner.J
- Sum := Sum + Compute.Blk.Inner.J * Compute.Ent.J;
- end loop Inner;
- end Ent;
- Compute.Sum := Compute.Sum + Compute.Blk.Sum;
- end Blk;
- end loop Outer;
- Record_Result(Sum);
- end Compute;
-
-
- Examples
-
- 17 Examples of labeled statements:
-
- 18 <<Here>> <<Ici>> <<Aqui>> <<Hier>> null;
-
- 19 <<After>> X := 1;
-
-
- Extensions to Ada 83
-
- 19.a {extensions to Ada 83} The requeue_statement is new.
-
- Wording Changes From Ada 83
-
- 19.b We define the syntactic category statement_identifier to
- simplify the description. It is used for labels, loop names, and
- block names. We define the entity associated with the implicit
- declarations of statement names.
-
- 19.c Completion includes completion caused by a transfer of
- control, although RM83-5.1(6) did not take this view.
-
-
-
- 5.2 Assignment Statements
-
- 1 [An assignment_statement replaces the current value of a variable with
- the result of evaluating an expression.]
-
-
- Syntax
-
- 2 assignment_statement ::=
- variable_name := expression;
-
-
- 3 The execution of an assignment_statement includes the evaluation of the
- expression and the assignment of the value of the expression into the target.
- {assignment operation [distributed]} {assign: see assignment operation} [An
- assignment operation (as opposed to an assignment_statement) is performed in
- other contexts as well, including object initialization and by-copy parameter
- passing.] {target (of an assignment operation)} {target (of an assignment_
- statement)} The target of an assignment operation is the view of the object
- to which a value is being assigned; the target of an assignment_statement is
- the variable denoted by the variable_name.
-
- 3.a Discussion: Don't confuse this notion of the ``target'' of an
- assignment with the notion of the ``target object'' of an entry call
- or requeue.
-
- 3.b Don't confuse the term ``assignment operation'' with the
- assignment_statement. The assignment operation is just one part of
- the execution of an assignment_statement. The assignment operation
- is also a part of the execution of various other constructs; see
- 7.6.1, ``Completion and Finalization'' for a complete list. Note
- that when we say, ``such-and-such is assigned to so-and-so'', we mean
- that the assignment operation is being applied, and that so-and-so is
- the target of the assignment operation.
-
-
- Name Resolution Rules
-
- 4 {expected type [assignment_statement variable_name]} The variable_name of
- an assignment_statement is expected to be of any nonlimited type. {expected
- type [assignment_statement expression]} The expected type for the expression
- is the type of the target.
-
- 4.a Implementation Note: An assignment_statement as a whole is a
- "complete context," so if the variable_name of an assignment_
- statement is overloaded, the expression can be used to help
- disambiguate it. For example:
-
- 4.b type P1 is access R1;
- type P2 is access R2;
-
- 4.c function F return P1;
- function F return P2;
-
- 4.d X : R1;
- begin
- F.all := X; -- Right hand side helps resolve left hand side
-
-
- Legality Rules
- 5 The target [denoted by the variable_name] shall be a variable.
-
- 6 If the target is of a tagged class-wide type T'Class, then the expression
- shall either be dynamically tagged, or of type T and tag-indeterminate (see
- 3.9.2).
-
- 6.a Reason: This is consistent with the general rule that a single
- dispatching operation shall not have both dynamically tagged and
- statically tagged operands. Note that for an object initialization
- (as opposed to the assignment_statement), a statically tagged
- initialization expression is permitted, since there is no chance for
- confusion (or Tag_Check failure). Also, in an object initialization,
- tag-indeterminate expressions of any type covered by T'Class would be
- allowed, but with an assignment_statement, that might not work if the
- tag of the target was for a type that didn't have one of the
- dispatching operations in the tag-indeterminate expression.
-
-
- Dynamic Semantics
-
- 7 {execution [assignment_statement]} For the execution of an assignment_
- statement, the variable_name and the expression are first evaluated in an
- arbitrary order.
-
- 7.a Ramification: Other rules of the language may require that the
- bounds of the variable be determined prior to evaluating the
- expression, but that does not necessarily require evaluation of the
- variable_name, as pointed out by the ACID.
-
- 8 When the type of the target is class-wide:
-
- 9 {controlling tag value [for the expression in an assignment_
- statement]} If the expression is tag-indeterminate (see 3.9.2),
- then the controlling tag value for the expression is the tag of
- the target;
-
- 9.a Ramification: See 3.9.2, ``Dispatching Operations of Tagged
- Types''.
-
- 10 {Tag_Check [partial]} {check, language-defined (Tag_Check)}
- {Constraint_Error (raised by failure of run-time check)}
- Otherwise [(the expression is dynamically tagged)], a check is
- made that the tag of the value of the expression is the same as
- that of the target; if this check fails, Constraint_Error is
- raised.
-
- 11 The value of the expression is converted to the subtype of the target.
- [The conversion might raise an exception (see 4.6).] {implicit subtype
- conversion [assignment_statement]}
-
- 11.a Ramification: 4.6, ``Type Conversions'' defines what actions
- and checks are associated with subtype conversion. For non-array
- subtypes, it is just a constraint check presuming the types match.
- For array subtypes, it checks the lengths and slides if the target is
- constrained. ``Sliding'' means the array doesn't have to have the
- same bounds, so long as it is the same length.
-
- 12 In cases involving controlled types, the target is finalized, and an
- anonymous object might be used as an intermediate in the assignment, as
- described in 7.6.1, ``Completion and Finalization''. {assignment operation}
- {assignment operation (during execution of an assignment_statement)} In any
- case, the converted value of the expression is then assigned to the target,
- which consists of the following two steps:
-
- 12.a To be honest: 7.6.1 actually says that finalization happens
- always, but unless controlled types are involved, this finalization
- during an assignment_statement does nothing.
-
- 13 The value of the target becomes the converted value.
-
- 14 If any part of the target is controlled, its value is adjusted as
- explained in clause 7.6. {adjustment [as part of assignment]}
-
- 14.a Ramification: If any parts of the object are controlled, abort
- is deferred during the assignment operation itself, but not
- during the rest of the execution of an assignment_statement.
-
-
- NOTES
- 15 (2) The tag of an object never changes; in particular, an assignment_
- statement does not change the tag of the target.
-
- 16 (3) The values of the discriminants of an object designated by an access
- value cannot be changed (not even by assigning a complete value to the
- object itself) since such objects are always constrained; however,
- subcomponents of such objects may be unconstrained.
-
- 16.a Ramification: The implicit subtype conversion described above for
- assignment_statements is performed only for the value of the
- right-hand side expression as a whole; it is not performed for
- subcomponents of the value.
-
- 16.b The determination of the type of the variable of an assignment_
- statement may require consideration of the expression if the variable
- name can be interpreted as the name of a variable designated by the
- access value returned by a function call, and similarly, as a
- component or slice of such a variable (see 8.6, ``The Context of
- Overload Resolution'').
-
-
- Examples
-
- 17 Examples of assignment statements:
-
- 18 Value := Max_Value - 1;
- Shade := Blue;
-
- 19 Next_Frame(F)(M, N) := 2.5; -- see 4.1.1
- U := Dot_Product(V, W); -- see 6.3
-
- 20 Writer := (Status => Open, Unit => Printer, Line_Count => 60); -- see 3.8.1
- Next_Car.all := (72074, null); -- see 3.10.1
-
- 21 Examples involving scalar subtype conversions:
-
- 22 I, J : Integer range 1 .. 10 := 5;
- K : Integer range 1 .. 20 := 15;
- ...
-
- 23 I := J; -- identical ranges
- K := J; -- compatible ranges
- J := K; -- will raise Constraint_Error if K > 10
-
- 24 Examples involving array subtype conversions:
-
- 25 A : String(1 .. 31);
- B : String(3 .. 33);
- ...
-
- 26 A := B; -- same number of components
-
- 27 A(1 .. 9) := "tar sauce";
- A(4 .. 12) := A(1 .. 9); -- A(1 .. 12) = "tartar sauce"
-
-
- NOTES
- 28 (4) Notes on the examples: Assignment_statements are allowed even in
- the case of overlapping slices of the same array, because the
- variable_name and expression are both evaluated before copying the value
- into the variable. In the above example, an implementation yielding A(1
- .. 12) = "tartartartar" would be incorrect.
-
-
- Extensions to Ada 83
-
- 28.a {extensions to Ada 83} We now allow user-defined finalization
- and value adjustment actions as part of assignment_statements (see
- 7.6, ``User-Defined Assignment and Finalization'').
-
- Wording Changes From Ada 83
-
- 28.b The special case of array assignment is subsumed by the
- concept of a subtype conversion, which is applied for all kinds of
- types, not just arrays. For arrays it provides ``sliding.'' For
- numeric types it provides conversion of a value of a universal type
- to the specific type of the target. For other types, it generally
- has no run-time effect, other than a constraint check.
-
- 28.c We now cover in a general way in 3.7.2 the erroneous execution
- possible due to changing the value of a discriminant when the
- variable in an assignment_statement is a subcomponent that depends on
- discriminants.
-
-
-
- 5.3 If Statements
-
- 1 [An if_statement selects for execution at most one of the enclosed
- sequences_of_statements, depending on the (truth) value of one or more
- corresponding conditions.]
-
-
- Syntax
-
- 2 if_statement ::=
- if condition then
- sequence_of_statements
- {elsif condition then
- sequence_of_statements}
- [else
- sequence_of_statements]
- end if;
-
- 3 condition ::= boolean_expression
-
-
- Name Resolution Rules
-
- 4 {expected type [condition]} A condition is expected to be of any boolean
- type.
-
-
- Dynamic Semantics
-
- 5 {execution [if_statement]} For the execution of an if_statement, the
- condition specified after if, and any conditions specified after elsif, are
- evaluated in succession (treating a final else as elsif True then), until one
- evaluates to True or all conditions are evaluated and yield False. If a
- condition evaluates to True, then the corresponding sequence_of_statements is
- executed; otherwise none of them is executed.
- 5.a Ramification: The part about all evaluating to False can't
- happen if there is an else, since that is herein considered
- equivalent to elsif True then.
-
-
- Examples
-
- 6 Examples of if statements:
-
- 7 if Month = December and Day = 31 then
- Month := January;
- Day := 1;
- Year := Year + 1;
- end if;
-
- 8 if Line_Too_Short then
- raise Layout_Error;
- elsif Line_Full then
- New_Line;
- Put(Item);
- else
- Put(Item);
- end if;
-
- 9 if My_Car.Owner.Vehicle /= My_Car then -- see 3.10.1
- Report ("Incorrect data");
- end if;
-
-
-
- 5.4 Case Statements
-
- 1 [A case_statement selects for execution one of a number of alternative
- sequences_of_statements; the chosen alternative is defined by the value of an
- expression.]
-
-
- Syntax
-
- 2 case_statement ::=
- case expression is
- case_statement_alternative
- {case_statement_alternative}
- end case;
-
- 3 case_statement_alternative ::=
- when discrete_choice_list =>
- sequence_of_statements
-
-
- Name Resolution Rules
-
- 4 {expected type [case expression]} The expression is expected to be of any
- discrete type. {expected type [case_statement_alternative discrete_choice]}
- The expected type for each discrete_choice is the type of the expression.
-
-
- Legality Rules
-
- 5 The expressions and discrete_ranges given as discrete_choices of a case_
- statement shall be static. [A discrete_choice others, if present, shall
- appear alone and in the last discrete_choice_list.]
-
- 6 The possible values of the expression shall be covered as follows:
-
- 7 If the expression is a name [(including a type_conversion or a
- function_call)] having a static and constrained nominal subtype,
- or is a qualified_expression whose subtype_mark denotes a static
- and constrained scalar subtype, then each non-others discrete_
- choice shall cover only values in that subtype, and each value of
- that subtype shall be covered by some discrete_choice [(either
- explicitly or by others)].
-
- 7.a Ramification: Although not official names of objects, a value
- conversion still has a defined nominal subtype, namely its
- target subtype. See 4.6.
-
- 8 If the type of the expression is root_integer, universal_integer,
- or a descendant of a formal scalar type, then the case_statement
- shall have an others discrete_choice.
-
- 8.a Reason: This is because the base range is implementation
- defined for root_integer and universal_integer, and not known
- statically in the case of a formal scalar type.
-
- 9 Otherwise, each value of the base range of the type of the
- expression shall be covered [(either explicitly or by others)].
-
- 10 Two distinct discrete_choices of a case_statement shall not cover the
- same value.
-
- 10.a Ramification: The goal of these coverage rules is that any
- possible value of the expression of a case_statement should be
- covered by exactly one discrete_choice of the case_statement, and
- that this should be checked at compile time. The goal is achieved in
- most cases, but there are two minor loopholes:
-
- 10.b If the expression reads an object with an invalid
- representation (e.g. an uninitialized object), then the
- value can be outside the covered range. This can happen
- for static constrained subtypes, as well as nonstatic or
- unconstrained subtypes. It cannot, however, happen if
- the case_statement has the discrete_choice others,
- because others covers all values, even those outside the
- subtype.
-
- 10.c If the compiler chooses to represent the value of an
- expression of an unconstrained subtype in a way that
- includes values outside the bounds of the subtype, then
- those values can be outside the covered range. For
- example, if X: Integer := Integer'Last;, and the case
- expression is X+1, then the implementation might choose
- to produce the correct value, which is outside the bounds
- of Integer. (It might raise Constraint_Error instead.)
- This case can only happen for non-generic subtypes that
- are either unconstrained or non-static (or both). It can
- only happen if there is no others discrete_choice.
-
- 10.d In the uninitialized variable case, the value might be
- anything; hence, any alternative can be chosen, or Constraint_Error
- can be raised. (We intend to prevent, however, jumping to random
- memory locations and the like.) In the out-of-range case, the
- behavior is more sensible: if there is an others, then the
- implementation may choose to raise Constraint_Error on the evaluation
- of the expression (as usual), or it may choose to correctly evaluate
- the expression and therefore choose the others alternative.
- Otherwise (no others), Constraint_Error is raised either way -- on
- the expression evaluation, or for the case_statement itself.
-
- 10.e For an enumeration type with a discontiguous set of internal
- codes (see 13.4), the only way to get values in between the proper
- values is via an object with an invalid representation; there is no
- ``out-of-range'' situation that can produce them.
-
-
- Dynamic Semantics
-
- 11 {execution [case_statement]} For the execution of a case_statement the
- expression is first evaluated.
-
- 12 If the value of the expression is covered by the discrete_choice_list of
- some case_statement_alternative, then the sequence_of_statements of the
- _alternative is executed.
-
- 13 {Overflow_Check [partial]} {check, language-defined (Overflow_Check)}
- {Constraint_Error (raised by failure of run-time check)} Otherwise (the value
- is not covered by any discrete_choice_list, perhaps due to being outside the
- base range), Constraint_Error is raised. {94-4768.e}
-
- 13.a Ramification: In this case, the value is outside the base
- range of its type, or is an invalid representation.
-
-
- NOTES
- 14 (5) The execution of a case_statement chooses one and only one
- alternative. Qualification of the expression of a case_statement by a
- static subtype can often be used to limit the number of choices that
- need be given explicitly.
-
-
- Examples
-
- 15 Examples of case statements:
-
- 16 case Sensor is
- when Elevation => Record_Elevation(Sensor_Value);
- when Azimuth => Record_Azimuth (Sensor_Value);
- when Distance => Record_Distance (Sensor_Value);
- when others => null;
- end case;
-
- 17
- case Today is
- when Mon => Compute_Initial_Balance;
- when Fri => Compute_Closing_Balance;
- when Tue .. Thu => Generate_Report(Today);
- when Sat .. Sun => null;
- end case;
-
- 18
- case Bin_Number(Count) is
- when 1 => Update_Bin(1);
- when 2 => Update_Bin(2);
- when 3 | 4 =>
- Empty_Bin(1);
- Empty_Bin(2);
- when others => raise Error;
- end case;
-
-
- Extensions to Ada 83
-
- 18.a {extensions to Ada 83} In Ada 83, the expression in a case_
- statement is not allowed to be of a generic formal type. This
- restriction is removed in Ada 9X; an others discrete_choice is
- required instead.
-
- 18.b In Ada 9X, a function call is the name of an object; this was
- not true in Ada 83 (see 4.1, ``Names''). This change makes the
- following case_statement legal:
- 18.c subtype S is Integer range 1..2;
- function F return S;
- case F is
- when 1 => ...;
- when 2 => ...;
- -- No others needed.
- end case;
-
- 18.d Note that the result subtype given in a function renaming_
- declaration is ignored; for a case_statement whose expression calls a
- such a function, the full coverage rules are checked using the result
- subtype of the original function. Note that predefined operators
- such as "+" have an unconstrained result subtype (see 4.5.1). Note
- that generic formal functions do not have static result subtypes.
- Note that the result subtype of an inherited subprogram need not
- correspond to any namable subtype; there is still a perfectly good
- result subtype, though.
-
- Wording Changes From Ada 83
-
- 18.e Ada 83 forgot to say what happens for ``legally''
- out-of-bounds values.
-
- 18.f We take advantage of rules and terms (e.g. cover a value)
- defined for discrete_choices and discrete_choice_lists in 3.8.1,
- ``Variant Parts and Discrete Choices''.
-
- 18.g In the Name Resolution Rule for the case expression, we no
- longer need RM83-5.4(3)'s ``which must be determinable independently
- of the context in which the expression occurs, but using the fact
- that the expression must be of a discrete type,'' because the
- expression is now a complete context. See 8.6, ``The Context of
- Overload Resolution''.
-
- 18.h Since type_conversions are now defined as names, their
- coverage rule is now covered under the general rule for names, rather
- than being separated out along with qualified_expressions.
-
-
-
- 5.5 Loop Statements
-
- 1 [A loop_statement includes a sequence_of_statements that is to be
- executed repeatedly, zero or more times.]
-
-
- Syntax
-
- 2 loop_statement ::=
- [loop_statement_identifier:]
- [iteration_scheme] loop
- sequence_of_statements
- end loop [loop_identifier];
-
- 3 iteration_scheme ::= while condition
- | for loop_parameter_specification
-
- 4 loop_parameter_specification ::=
- defining_identifier in [reverse] discrete_subtype_definition
-
- 5 If a loop_statement has a loop_statement_identifier, then the
- identifier shall be repeated after the end loop; otherwise, there shall
- not be an identifier after the end loop.
-
-
- Static Semantics
-
- 6 {loop parameter} A loop_parameter_specification declares a loop
- parameter, which is an object whose subtype is that defined by the discrete_
- subtype_definition. {parameter: see also loop parameter}
-
-
- Dynamic Semantics
-
- 7 {execution [loop_statement]} For the execution of a loop_statement, the
- sequence_of_statements is executed repeatedly, zero or more times, until the
- loop_statement is complete. The loop_statement is complete when a transfer
- of control occurs that transfers control out of the loop, or, in the case of
- an iteration_scheme, as specified below.
-
- 8 {execution [loop_statement with a while iteration_scheme]} For the
- execution of a loop_statement with a while iteration_scheme, the condition is
- evaluated before each execution of the sequence_of_statements; if the value
- of the condition is True, the sequence_of_statements is executed; if False,
- the execution of the loop_statement is complete.
-
- 9 {execution [loop_statement with a for iteration_scheme]} {elaboration
- [loop_parameter_specification]} For the execution of a loop_statement with a
- for iteration_scheme, the loop_parameter_specification is first elaborated.
- This elaboration creates the loop parameter and elaborates the discrete_
- subtype_definition. If the discrete_subtype_definition defines a subtype
- with a null range, the execution of the loop_statement is complete.
- Otherwise, the sequence_of_statements is executed once for each value of the
- discrete subtype defined by the discrete_subtype_definition (or until the
- loop is left as a consequence of a transfer of control). {assignment
- operation (during execution of a for loop)} Prior to each such iteration, the
- corresponding value of the discrete subtype is assigned to the loop
- parameter. These values are assigned in increasing order unless the reserved
- word reverse is present, in which case the values are assigned in decreasing
- order.
-
- 9.a Ramification: The order of creating the loop parameter and
- evaluating the discrete_subtype_definition doesn't matter, since the
- creation of the loop parameter has no side effects (other than
- possibly raising Storage_Error, but anything can do that).
-
-
- NOTES
- 10 (6) A loop parameter is a constant; it cannot be updated within the
- sequence_of_statements of the loop (see 3.3).
-
- 11 (7) An object_declaration should not be given for a loop parameter,
- since the loop parameter is automatically declared by the loop_
- parameter_specification. The scope of a loop parameter extends from the
- loop_parameter_specification to the end of the loop_statement, and the
- visibility rules are such that a loop parameter is only visible within
- the sequence_of_statements of the loop.
-
- 11.a Implementation Note: An implementation could give a warning if a
- variable is hidden by a loop_parameter_specification.
-
- 12 (8) The discrete_subtype_definition of a for loop is elaborated just
- once. Use of the reserved word reverse does not alter the discrete
- subtype defined, so that the following iteration_schemes are not
- equivalent; the first has a null range.
-
- 13 for J in reverse 1 .. 0
- for J in 0 .. 1
-
- 13.a Ramification: If a loop_parameter_specification has a static
- discrete range, the subtype of the loop parameter is static.
-
-
- Examples
-
- 14 Example of a loop statement without an iteration scheme:
-
- 15 loop
- Get(Current_Character);
- exit when Current_Character = '*';
- end loop;
-
- 16 Example of a loop statement with a while iteration scheme:
-
- 17 while Bid(N).Price < Cut_Off.Price loop
- Record_Bid(Bid(N).Price);
- N := N + 1;
- end loop;
-
- 18 Example of a loop statement with a for iteration scheme:
-
- 19 for J in Buffer'Range loop -- works even with a null range
- if Buffer(J) /= Space then
- Put(Buffer(J));
- end if;
- end loop;
-
- 20 Example of a loop statement with a name:
-
- 21 Summation:
- while Next /= Head loop -- see 3.10.1
- Sum := Sum + Next.Value;
- Next := Next.Succ;
- end loop Summation;
-
-
- Wording Changes From Ada 83
-
- 21.a The constant-ness of loop parameters is specified in 3.3,
- ``Objects and Named Numbers''.
-
-
-
- 5.6 Block Statements
-
- 1 [A block_statement encloses a handled_sequence_of_statements optionally
- preceded by a declarative_part.]
-
-
- Syntax
-
- 2 block_statement ::=
- [block_statement_identifier:]
- [declare
- declarative_part]
- begin
- handled_sequence_of_statements
- end [block_identifier];
-
- 3 If a block_statement has a block_statement_identifier, then the
- identifier shall be repeated after the end; otherwise, there shall not be
- an identifier after the end.
-
-
- Static Semantics
-
- 4 A block_statement that has no explicit declarative_part has an implicit
- empty declarative_part.
- 4.a Ramification: Thus, other rules can always refer to the
- declarative_part of a block_statement.
-
-
- Dynamic Semantics
-
- 5 {execution [block_statement]} The execution of a block_statement consists
- of the elaboration of its declarative_part followed by the execution of its
- handled_sequence_of_statements.
-
-
- Examples
-
- 6 Example of a block statement with a local variable:
-
- 7 Swap:
- declare
- Temp : Integer;
- begin
- Temp := V; V := U; U := Temp;
- end Swap;
-
- 7.a Ramification: If task objects are declared within a block_
- statement whose execution is completed, the block_statement is not
- left until all its dependent tasks are terminated (see 7.6). This
- rule applies to completion caused by a transfer of control.
-
- 7.b Within a block_statement, the block name can be used in
- expanded names denoting local entities such as Swap.Temp in the above
- example (see 4.1.3).
-
-
- Wording Changes From Ada 83
-
- 7.c The syntax rule for block_statement now uses the syntactic
- category handled_sequence_of_statements.
-
-
-
- 5.7 Exit Statements
-
- 1 [An exit_statement is used to complete the execution of an enclosing
- loop_statement; the completion is conditional if the exit_statement includes
- a condition.] {94-4605.a} {94-4560.a}
-
-
- Syntax
-
- 2 exit_statement ::=
- exit [loop_name] [when condition];
-
-
- Name Resolution Rules
-
- 3 The loop_name, if any, in an exit_statement shall resolve to denote a
- loop_statement.
-
-
- Legality Rules
-
- 4 {apply (to a loop_statement by an exit_statement)} Each exit_statement
- applies to a loop_statement; this is the loop_statement being exited. An
- exit_statement with a name is only allowed within the loop_statement denoted
- by the name, and applies to that loop_statement. An exit_statement without a
- name is only allowed within a loop_statement, and applies to the innermost
- enclosing one. An exit_statement that applies to a given loop_statement
- shall not appear within a body or accept_statement, if this construct is
- itself enclosed by the given loop_statement.
-
-
- Dynamic Semantics
-
- 5 {execution [exit_statement]} For the execution of an exit_statement, the
- condition, if present, is first evaluated. If the value of the condition is
- True, or if there is no condition, a transfer of control is done to complete
- the loop_statement. If the value of the condition is False, no transfer of
- control takes place.
-
-
- NOTES
- 6 (9) Several nested loops can be exited by an exit_statement that names
- the outer loop.
-
-
- Examples
-
- 7 Examples of loops with exit statements:
-
- 8 for N in 1 .. Max_Num_Items loop
- Get_New_Item(New_Item);
- Merge_Item(New_Item, Storage_File);
- exit when New_Item = Terminal_Item;
- end loop;
-
- 9 Main_Cycle:
- loop
- -- initial statements
- exit Main_Cycle when Found;
- -- final statements
- end loop Main_Cycle;
-
-
-
- 5.8 Goto Statements
-
- 1 [A goto_statement specifies an explicit transfer of control from this
- statement to a target statement with a given label.]
-
-
- Syntax
-
- 2 goto_statement ::= goto label_name;
-
-
- Name Resolution Rules
-
- 3 {target statement (of a goto_statement)} The label_name shall resolve to
- denote a label; the statement with that label is the target statement.
-
-
- Legality Rules
-
- 4 The innermost sequence_of_statements that encloses the target statement
- shall also enclose the goto_statement.
-
- 4.a Ramification: The goto_statement can be a statement of an
- inner sequence_.
-
- Furthermore, if a goto_statement is enclosed by an accept_statement or a
- body, then the target statement shall not be outside this enclosing
- construct.
-
- 4.b Ramification: It follows from the previous rule that if the
- target statement is enclosed by such a construct, then the goto_
- statement cannot be outside.
-
-
- Dynamic Semantics
-
- 5 {execution [goto_statement]} The execution of a goto_statement transfers
- control to the target statement, completing the execution of any compound_
- statement that encloses the goto_statement but does not enclose the target.
-
-
- NOTES
- 6 (10) The above rules allow transfer of control to a statement of an
- enclosing sequence_of_statements but not the reverse. Similarly, they
- prohibit transfers of control such as between alternatives of a case_
- statement, if_statement, or select_statement; between exception_
- handlers; or from an exception_handler of a handled_sequence_of_
- statements back to its sequence_of_statements.
-
-
- Examples
-
- 7 Example of a loop containing a goto statement:
-
- 8 <<Sort>>
- for I in 1 .. N-1 loop
- if A(I) > A(I+1) then
- Exchange(A(I), A(I+1));
- goto Sort;
- end if;
- end loop;
-
-
-
- Section 6: Subprograms
-
-
- 1 {subprogram} {procedure} {function} A subprogram is a program unit or
- intrinsic operation whose execution is invoked by a subprogram call. There
- are two forms of subprogram: procedures and functions. A procedure call is a
- statement; a function call is an expression and returns a value. The
- definition of a subprogram can be given in two parts: a subprogram
- declaration defining its interface, and a subprogram_body defining its
- execution. [Operators and enumeration literals are functions.]
-
- 1.a To be honest: A function call is an expression, but more
- specifically it is a name.
-
- 2 {callable entity} A callable entity is a subprogram or entry (see Section
- 9). {call} A callable entity is invoked by a call; that is, a subprogram
- call or entry call. {callable construct} A callable construct is a construct
- that defines the action of a call upon a callable entity: a subprogram_body,
- entry_body, or accept_statement.
-
- 2.a Ramification: Note that ``callable entity'' includes
- predefined operators, enumeration literals, and abstract subprograms.
- ``Call'' includes calls of these things. They do not have callable
- constructs, since they don't have completions.
-
-
-
- 6.1 Subprogram Declarations
-
- 1 [A subprogram_declaration declares a procedure or function.]
- Syntax
-
- 2 subprogram_declaration ::= subprogram_specification;
-
- 3 abstract_subprogram_declaration ::= subprogram_specification is abstract;
-
- 4 subprogram_specification ::=
- procedure defining_program_unit_name parameter_profile
- | function defining_designator parameter_and_result_profile
-
- 5 designator ::= [parent_unit_name . ]identifier | operator_symbol
-
- 6 defining_designator ::= defining_program_unit_name | defining_operator_symb\
- ol
-
- 7 defining_program_unit_name ::= [parent_unit_name . ]defining_identifier
-
- 8 [The optional parent_unit_name is only allowed for library units (see
- 10.1.1).]
-
-
- 9 operator_symbol ::= string_literal
-
- 10 The sequence of characters in an operator_symbol shall correspond to
- an operator belonging to one of the six classes of operators defined in
- clause 4.5 (spaces are not allowed and the case of letters is not
- significant).
-
-
- 11 defining_operator_symbol ::= operator_symbol
-
- 12 parameter_profile ::= [formal_part]
-
- 13 parameter_and_result_profile ::= [formal_part] return subtype_mark
-
- 14 formal_part ::=
- (parameter_specification {; parameter_specification})
-
- 15 parameter_specification ::=
- defining_identifier_list : mode subtype_mark [:= default_expression]
- | defining_identifier_list : access_definition [:= default_expression]
-
- 16 mode ::= [in] | in out | out
-
-
- Name Resolution Rules
-
- 17 {formal parameter (of a subprogram)} A formal parameter is an object
- [directly visible within a subprogram_body] that represents the actual
- parameter passed to the subprogram in a call; it is declared by a parameter_
- specification. {expected type [parameter default_expression]} For a formal
- parameter, the expected type for its default_expression, if any, is that of
- the formal parameter. {parameter: see formal parameter}
-
-
- Legality Rules
-
- 18 {parameter mode} The parameter mode of a formal parameter conveys the
- direction of information transfer with the actual parameter: in, in out, or
- out. Mode in is the default, and is the mode of a parameter defined by an
- access_definition. The formal parameters of a function, if any, shall have
- the mode in.
-
- 18.a Ramification: Access parameters are permitted. This
- restriction to in parameters is primarily a methodological
- restriction, though it also simplifies implementation for some
- compiler technologies.
-
- 19 A default_expression is only allowed in a parameter_specification for a
- formal parameter of mode in.
-
- 20 {requires a completion [subprogram_declaration]} {requires a completion
- [generic_subprogram_declaration]} A subprogram_declaration or a generic_
- subprogram_declaration requires a completion: [a body, a renaming_
- declaration (see 8.5), or a pragma Import (see B.1)]. [A completion is not
- allowed for an abstract_subprogram_declaration.]
-
- 20.a Ramification: Abstract subprograms are not declared by
- subprogram_declarations, and so do not require completion. Protected
- subprograms are declared by subprogram_declarations, and so require
- completion. Note that an abstract subprogram is a subprogram, and a
- protected subprogram is a subprogram, but a generic subprogram is not
- a subprogram.
-
- 21 A name that denotes a formal parameter is not allowed within the formal_
- part in which it is declared, nor within the formal_part of a corresponding
- body or accept_statement.
-
- 21.a Ramification: By contrast, generic_formal_parameter_declara-
- tions are visible to subsequent declarations in the same generic_
- formal_part.
-
-
- Static Semantics
-
- 22 {profile} The profile of (a view of) a callable entity is either a
- parameter_profile or parameter_and_result_profile[; it embodies information
- about the interface to that entity -- for example, the profile includes
- information about parameters passed to the callable entity. All callable
- entities have a profile -- enumeration literals, other subprograms, and
- entries. An access-to-subprogram type has a designated profile.] Associated
- with a profile is a calling convention. A subprogram_declaration declares a
- procedure or a function, as indicated by the initial reserved word, with name
- and profile as given by its specification.
-
- 23 {nominal subtype [of a formal parameter]} The nominal subtype of a
- formal parameter is the subtype denoted by the subtype_mark, or defined by
- the access_definition, in the parameter_specification.
-
- 24 {access parameter} An access parameter is a formal in parameter
- specified by an access_definition. An access parameter is of an anonymous
- general access-to-variable type (see 3.10). [Access parameters allow
- dispatching calls to be controlled by access values.]
-
- 25 {subtypes (of a profile)} The subtypes of a profile are:
-
- 26 For any non-access parameters, the nominal subtype of the
- parameter.
-
- 27 For any access parameters, the designated subtype of the
- parameter type.
-
- 28 For any result, the result subtype.
-
- 29 [{types (of a profile)} The types of a profile are the types of those
- subtypes.]
-
- 30 [A subprogram declared by an abstract_subprogram_declaration is
- abstract; a subprogram declared by a subprogram_declaration is not. See
- 3.9.3, ``Abstract Types and Subprograms''.]
-
-
- Dynamic Semantics
-
- 31 {elaboration [subprogram_declaration]} {elaboration [abstract_
- subprogram_declaration]} The elaboration of a subprogram_declaration or an
- abstract_subprogram_declaration has no effect.
-
-
- NOTES
- 32 (1) A parameter_specification with several identifiers is equivalent to
- a sequence of single parameter_specifications, as explained in 3.3.
-
- 33 (2) Abstract subprograms do not have bodies, and cannot be used in a
- nondispatching call (see 3.9.3, ``Abstract Types and Subprograms'').
-
- 34 (3) The evaluation of default_expressions is caused by certain calls, as
- described in 6.4.1. They are not evaluated during the elaboration of
- the subprogram declaration.
-
- 35 (4) Subprograms can be called recursively and can be called concurrently
- from multiple tasks.
-
-
- Examples
-
- 36 Examples of subprogram declarations:
-
- 37 procedure Traverse_Tree;
- procedure Increment(X : in out Integer);
- procedure Right_Indent(Margin : out Line_Size); -- see 3.5.4
- procedure Switch(From, To : in out Link); -- see 3.10.1
-
- 38 function Random return Probability; -- see 3.5.7
-
- 39 function Min_Cell(X : Link) return Cell; -- see 3.10.1
- function Next_Frame(K : Positive) return Frame; -- see 3.10
- function Dot_Product(Left, Right : Vector) return Real; -- see 3.6
-
- 40 function "*"(Left, Right : Matrix) return Matrix; -- see 3.6
-
- 41 Examples of in parameters with default expressions:
-
- 42 procedure Print_Header(Pages : in Natural;
- Header : in Line := (1 .. Line'Last => ' '); -- see 3.6
- Center : in Boolean := True);
-
-
- Extensions to Ada 83
-
- 42.a {extensions to Ada 83} The syntax for abstract_subprogram_
- declaration is added. The syntax for parameter_specification is
- revised to allow for access parameters (see 3.10)
-
- 42.b Program units that are library units may have a parent_unit_
- name to indicate the parent of a child (see Section 10).
-
- Wording Changes From Ada 83
-
- 42.c We have incorporated the rules from RM83-6.5, ``Function
- Subprograms'' here and in 6.3, ``Subprogram Bodies''
-
- 42.d We have incorporated the definitions of RM83-6.6, ``Parameter
- and Result Type Profile - Overloading of Subprograms'' here.
-
- 42.e The syntax rule for defining_operator_symbol is new. It is
- used for the defining occurrence of an operator_symbol, analogously
- to defining_identifier. Usage occurrences use the direct_name or
- selector_name syntactic categories. The syntax rules for defining_
- designator and defining_program_unit_name are new.
- 6.2 Formal Parameter Modes
-
- 1 [A parameter_specification declares a formal parameter of mode in, in
- out, or out.]
-
-
- Static Semantics
-
- 2 {pass by copy} {by copy parameter passing} {copy parameter passing} {pass
- by reference} {by reference parameter passing} {reference parameter passing}
- A parameter is passed either by copy or by reference. [When a parameter is
- passed by copy, the formal parameter denotes a separate object from the
- actual parameter, and any information transfer between the two occurs only
- before and after executing the subprogram. When a parameter is passed by
- reference, the formal parameter denotes (a view of) the object denoted by the
- actual parameter; reads and updates of the formal parameter directly
- reference the actual parameter object.]
-
- 3 {by-copy type} A type is a by-copy type if it is an elementary type, or
- if it is a descendant of a private type whose full type is a by-copy type. A
- parameter of a by-copy type is passed by copy.
-
- 4 {by-reference type} A type is a by-reference type if it is a descendant
- of one of the following:
-
- 5 a tagged type;
-
- 6 a task or protected type;
-
- 7 a nonprivate type with the reserved word limited in its
- declaration;
-
- 7.a Ramification: A limited private type is by-reference only if it
- falls under one of the other categories.
-
- 8 a composite type with a subcomponent of a by-reference type;
-
- 9 a private type whose full type is a by-reference type.
-
- 10 A parameter of a by-reference type is passed by reference. {associated
- object (of a value of a by-reference type)} Each value of a by-reference type
- has an associated object. For a parenthesized expression, qualified_
- expression, or type_conversion, this object is the one associated with the
- operand. {94-4774.a}
-
- 10.a Ramification: By-reference parameter passing makes sense only
- if there is an object to reference; hence, we define such an object
- for each case.
-
- 10.b Since tagged types are by-reference types, this implies that
- every value of a tagged type has an associated object. This
- simplifies things, because we can define the tag to be a property of
- the object, and not of the value of the object, which makes it
- clearer that object tags never change.
-
- 10.c We considered simplifying things even more by making every
- value (and therefore every expression) have an associated object.
- After all, there is little semantic difference between a constant
- object and a value. However, this would cause problems for untagged
- types. In particular, we would have to do a constraint check on
- every read of a type conversion (or a renaming thereof) in certain
- cases.
-
- 10.d We do not want this definition to depend on the view of the
- type; privateness is essentially ignored for this definition.
- Otherwise, things would be confusing (does the rule apply at the call
- site, at the site of the declaration of the subprogram, at the site
- of the return_statement?), and requiring different calls to use
- different mechanisms would be an implementation burden.
-
- 10.e C.6, ``Shared Variable Control'' says that a composite type
- with an atomic or volatile subcomponent is a by-reference type, among
- other things.
-
- 10.f {associated object (of a value of a limited type)} Every value
- of a limited by-reference type is the value of one and only one
- limited object. The associated object of a value of a limited
- by-reference type is the object whose value it represents. {same
- value (for a limited type)} Two values of a limited by-reference type
- are the same if and only if they represent the value of the same
- object.
-
- 10.g We say ``by-reference'' above because these statements are not
- always true for limited private types whose underlying type is
- nonlimited (unfortunately).
-
- 11 {unspecified [partial]} For parameters of other types, it is unspecified
- whether the parameter is passed by copy or by reference.
-
- 11.a Discussion: There is no need to incorporate the discussion of
- AI-00178, which requires pass-by-copy for certain kinds of actual
- parameters, while allowing pass-by-reference for others. This is
- because we explicitly indicate that a function creates an anonymous
- constant object for its result, unless the type is a
- return-by-reference type (see 6.5). We also provide a special
- dispensation for instances of Unchecked_Conversion to return by
- reference, even if the result type is not a return-by-reference type
- (see 13.9).
-
-
- Bounded (Run-Time) Errors
-
- 12 {bounded error} {distinct access paths} {access paths (distinct)}
- {aliasing: see distinct access paths} If one name denotes a part of a formal
- parameter, and a second name denotes a part of a distinct formal parameter or
- an object that is not part of a formal parameter, then the two names are
- considered distinct access paths. If an object is of a type for which the
- parameter passing mechanism is not specified, then it is a bounded error to
- assign to the object via one access path, and then read the value of the
- object via a distinct access path, unless the first access path denotes a
- part of a formal parameter that no longer exists at the point of the second
- access [(due to leaving the corresponding callable construct).] {94-4573.a}
- {94-4572.a} {94-4751.a} {94-4572.b} {94-4751.b} {94-4572.c} {94-4751.c}
- {Program_Error (raised by failure of run-time check)} The possible
- consequences are that Program_Error is raised, or the newly assigned value is
- read, or some old value of the object is read.
-
- 12.a Discussion: For example, if we call ``P(X => Global_Variable,
- Y => Global_Variable)'', then within P, the names ``X'', ``Y'', and
- ``Global_Variable'' are all distinct access paths. If Global_
- Variable's type is neither pass-by-copy nor pass-by-reference, then
- it is a bounded error to assign to Global_Variable and then read X or
- Y, since the language does not specify whether the old or the new
- value would be read. On the other hand, if Global_Variable's type is
- pass-by-copy, then the old value would always be read, and there is
- no error. Similarly, if Global_Variable's type is defined by the
- language to be pass-by-reference, then the new value would always be
- read, and again there is no error.
-
- 12.b Reason: We are saying assign here, not update, because
- updating any subcomponent is considered to update the enclosing
- object.
-
- 12.c The ``still exists'' part is so that a read after the
- subprogram returns is OK.
-
- 12.d If the parameter is of a by-copy type, then there is no issue
- here -- the formal is not a view of the actual. If the parameter is
- of a by-reference type, then the programmer may depend on updates
- through one access path being visible through some other access path,
- just as if the parameter were of an access type.
-
- 12.e Implementation Note: The implementation can keep a copy in a
- register of a parameter whose parameter-passing mechanism is not
- specified. If a different access path is used to update the object
- (creating a bounded error situation), then the implementation can
- still use the value of the register, even though the in-memory
- version of the object has been changed. However, to keep the error
- properly bounded, if the implementation chooses to read the in-memory
- version, it has to be consistent -- it cannot then assume that
- something it has proven about the register is true of the memory
- location. For example, suppose the formal parameter is L, the value
- of L(6) is now in a register, and L(6) is used in an indexed_
- component as in ``A(L(6)) := 99;'', where A has bounds 1..3. If the
- implementation can prove that the value for L(6) in the register is
- in the range 1..3, then it need not perform the constraint check if
- it uses the register value. However, if the memory value of L(6) has
- been changed to 4, and the implementation uses that memory value,
- then it had better not alter memory outside of A.
-
- 12.f Note that the rule allows the implementation to pass a
- parameter by reference and then keep just part of it in a register,
- or, equivalently, to pass part of the parameter by reference and
- another part by copy.
-
- 12.g Reason: We do not want to go so far as to say that the mere
- presence of aliasing is wrong. We wish to be able to write the
- following sorts of things in standard Ada:
-
- 12.h procedure Move ( Source : in String;
- Target : out String;
- Adjust : in Length_Adjustment :=
- (Drop => Right;
- Justify => Left;
- Pad => Representations.Pad ) );
- -- Copies elements from Source to Target (safely if they overlap)
-
- 12.i This is from the standard string handling package. It would
- be embarrassing if this couldn't be written in Ada!
-
- 12.j The ``then'' before ``read'' in the rule implies that the
- implementation can move a read to an earlier place in the code, but
- not to a later place after a potentially aliased assignment. Thus,
- if the subprogram reads one of its parameters into a local variable,
- and then updates another potentially aliased one, the local copy is
- safe -- it is known to have the old value. For example, the
- above-mentioned Move subprogram can be implemented by copying Source
- into a local variable before assigning into Target.
-
- 12.k For an assignment_statement assigning one array parameter to
- another, the implementation has to check which direction to copy at
- run time, in general, in case the actual parameters are overlapping
- slices. For example:
-
- 12.l procedure Copy(X : in out String; Y: String) is
- begin
- X := Y;
- end Copy;
-
- 12.m It would be wrong for the compiler to assume that X and Y do
- not overlap (unless, of course, it can prove otherwise).
-
-
- NOTES
- 13 (5) A formal parameter of mode in is a constant view (see 3.3); it
- cannot be updated within the subprogram_body.
-
-
- Extensions to Ada 83
-
- 13.a {extensions to Ada 83} The value of an out parameter may be
- read. An out parameter is treated like a declared variable without
- an explicit initial expression.
-
- Wording Changes From Ada 83
-
- 13.b Discussion of copy-in for parts of out parameters is now
- covered in 6.4.1, ``Parameter Associations''.
-
- 13.c The concept of a by-reference type is new to Ada 9X.
-
- 13.d We now cover in a general way in 3.7.2 the rule regarding
- erroneous execution when a discriminant is changed and one of the
- parameters depends on the discriminant.
-
-
-
- 6.3 Subprogram Bodies
-
- 1 [A subprogram_body specifies the execution of a subprogram.]
-
-
- Syntax
-
- 2 subprogram_body ::=
- subprogram_specification is
- declarative_part
- begin
- handled_sequence_of_statements
- end [designator];
-
- 3 If a designator appears at the end of a subprogram_body, it shall
- repeat the defining_designator of the subprogram_specification.
-
-
- Legality Rules
-
- 4 [In contrast to other bodies,] a subprogram_body need not be the
- completion of a previous declaration[, in which case the body declares the
- subprogram]. If the body is a completion, it shall be the completion of a
- subprogram_declaration or generic_subprogram_declaration. The profile of a
- subprogram_body that completes a declaration shall conform fully to that of
- the declaration. {full conformance (required)}
-
-
- Static Semantics
-
- 5 A subprogram_body is considered a declaration. It can either complete a
- previous declaration, or itself be the initial declaration of the subprogram.
-
-
- Dynamic Semantics
-
- 6 {elaboration [non-generic subprogram_body]} The elaboration of a
- non-generic subprogram_body has no other effect than to establish that the
- subprogram can from then on be called without failing the Elaboration_Check.
-
- 6.a Ramification: See 12.2 for elaboration of a generic body.
- Note that protected subprogram_bodies never get elaborated; the
- elaboration of the containing protected_body allows them to be called
- without failing the Elaboration_Check.
-
- 7 {execution [subprogram_body]} [The execution of a subprogram_body is
- invoked by a subprogram call.] For this execution the declarative_part is
- elaborated, and the handled_sequence_of_statements is then executed.
-
-
- Examples
-
- 8 Example of procedure body:
-
- 9 procedure Push(E : in Element_Type; S : in out Stack) is
- begin
- if S.Index = S.Size then
- raise Stack_Overflow;
- else
- S.Index := S.Index + 1;
- S.Space(S.Index) := E;
- end if;
- end Push;
-
- 10 Example of a function body:
-
- 11 function Dot_Product(Left, Right : Vector) return Real is
- Sum : Real := 0.0;
- begin
- Check(Left'First = Right'First and Left'Last = Right'Last);
- for J in Left'Range loop
- Sum := Sum + Left(J)*Right(J);
- end loop;
- return Sum;
- end Dot_Product;
-
-
- Extensions to Ada 83
-
- 11.a {extensions to Ada 83} A renaming_declaration may be used
- instead of a subprogram_body.
-
- Wording Changes From Ada 83
-
- 11.b The syntax rule for subprogram_body now uses the syntactic
- category handled_sequence_of_statements.
-
- 11.c The declarative_part of a subprogram_body is now required;
- that doesn't make any real difference, because a declarative_part can
- be empty.
-
- 11.d We have incorporated some rules from RM83-6.5 here.
-
- 11.e RM83 forgot to restrict the definition of elaboration of a
- subprogram_body to non-generics.
-
-
-
- 6.3.1 Conformance Rules
-
- 1 {conformance} [When subprogram profiles are given in more than one place,
- they are required to conform in one of four ways: type conformance, mode
- conformance, subtype conformance, or full conformance.]
-
-
- Static Semantics
-
- 2 {convention} {calling convention} [As explained in B.1, ``Interfacing
- Pragmas'', a convention can be specified for an entity. For a callable
- entity or access-to-subprogram type, the convention is called the calling
- convention.] The following conventions are defined by the language:
-
- 3 {Ada calling convention} {calling convention (Ada)} The default
- calling convention for any subprogram not listed below is Ada.
- [A pragma Convention, Import, or Export may be used to override
- the default calling convention (see B.1)].
-
- 3.a Ramification: See also the rule about renamings-as-body in
- 8.5.4.
-
- 4 {Intrinsic calling convention} {calling convention (Intrinsic)}
- The Intrinsic calling convention represents subprograms that are
- ``built in'' to the compiler. The default calling convention is
- Intrinsic for the following:
-
- 5 an enumeration literal;
-
- 6 a "/=" operator declared implicitly due to the declaration
- of "=" (see 6.6);
-
- 7 any other implicitly declared subprogram unless it is a
- dispatching operation of a tagged type;
-
- 8 an inherited subprogram of a generic formal tagged type
- with unknown discriminants; {94-4774.b}
-
- 9 an attribute that is a subprogram;
-
- 10 a subprogram declared immediately within a protected_body.
-
- 11 [The Access attribute is not allowed for Intrinsic
- subprograms.] {94-4774.b}
-
- 11.a Ramification: The Intrinsic calling convention really
- represents any number of calling conventions at the machine code
- level; the compiler might have a different instruction sequence
- for each intrinsic. That's why the Access attribute is
- disallowed. We do not wish to require the implementation to
- generate an out of line body for an intrinsic.
-
- 11.b Whenever we wish to disallow the Access attribute in
- order to ease implementation, we make the subprogram Intrinsic.
- Several language-defined subprograms have ``pragma
- Convention(Intrinsic, ...);''. An implementation might actually
- implement this as ``pragma Import(Intrinsic, ...);'', if there
- is really no body, and the implementation of the subprogram is
- built into the code generator.
-
- 11.c Subprograms declared in protected_bodies will generally
- have a special calling convention so as to pass along the
- identification of the current instance of the protected type.
- The convention is not protected since such local subprograms
- need not contain any ``locking'' logic since they are not
- callable via ``external'' calls; this rule prevents an access
- value designating such a subprogram from being passed outside
- the protected unit.
-
- 11.d The ``implicitly declared subprogram'' above refers to
- predefined operators (other than the "=" of a tagged type) and
- the inherited subprograms of untagged types.
-
- 12 {protected calling convention} {calling convention (protected)}
- The default calling convention is protected for a protected
- subprogram, and for an access-to-subprogram type with the
- reserved word protected in its definition.
-
- 13 {entry calling convention} {calling convention (entry)} The
- default calling convention is entry for an entry.
-
- 14 Of these four conventions, only Ada and Intrinsic are allowed as a
- convention_identifier in a pragma Convention, Import, or Export.
-
- 14.a Discussion: The names of the protected and entry calling
- conventions cannot be used in the interfacing pragmas. Note that
- protected and entry are reserved words.
-
- 15 {type conformance} {profile (type conformant)} Two profiles are type
- conformant if they have the same number of parameters, and both have a result
- if either does, and corresponding parameter and result types are the same,
- or, for access parameters, corresponding designated types are the same.
- {type profile: see profile, type conformant}
-
- 15.a Discussion: For access parameters, the designated types have
- to be the same for type conformance, not the access types, since in
- general each access parameter has its own anonymous access type,
- created when the subprogram is called. Of course, corresponding
- parameters have to be either both access parameters or both not
- access parameters.
-
- 16 {mode conformance} {profile (mode conformant)} Two profiles are mode
- conformant if they are type-conformant, and corresponding parameters have
- identical modes, and, for access parameters, the designated subtypes
- statically match. {statically matching [required]}
-
- 17 {subtype conformance} {profile (subtype conformant)} Two profiles are
- subtype conformant if they are mode-conformant, corresponding subtypes of the
- profile statically match, and the associated calling conventions are the
- same. {94-4774.b} The profile of a generic formal subprogram is not
- subtype-conformant with any other profile. {statically matching [required]}
-
- 17.a Ramification: {generic contract issue [partial]}
-
- 18 {full conformance (for profiles)} {profile (fully conformant)} Two
- profiles are fully conformant if they are subtype-conformant, and
- corresponding parameters have the same names and have default_expressions
- that are fully conformant with one another.
-
- 18.a Ramification: Full conformance requires subtype conformance,
- which requires the same calling conventions. However, the calling
- convention of the declaration and body of a subprogram or entry are
- always the same by definition.
-
- 19 {full conformance (for expressions)} Two expressions are fully
- conformant if, [after replacing each use of an operator with the equivalent
- function_call:]
-
- 20 each constituent construct of one corresponds to an instance of
- the same syntactic category in the other, except that an expanded
- name may correspond to a direct_name (or character_literal) or to
- a different expanded name in the other; and
-
- 21 each direct_name, character_literal, and selector_name that is
- not part of the prefix of an expanded name in one denotes the
- same declaration as the corresponding direct_name, character_
- literal, or selector_name in the other; and {94-4718.c}
- {94-4752.a}
-
- 21.a Ramification: Note that it doesn't say ``respectively'' because
- a direct_name can correspond to a selector_name, and vice-versa,
- by the previous bullet. This rule allows the prefix of an
- expanded name to be removed, or replaced with a different prefix
- that denotes a renaming of the same entity. However, it does
- not allow a direct_name or selector_name to be replaced with one
- denoting a distinct renaming (except for direct_names and
- selector_names in prefixes of expanded names). Note that calls
- using operator notation are equivalent to calls using prefix
- notation.
-
- 21.b Given the following declarations:
-
- 21.c package A is
- function F(X : Integer := 1) return Boolean;
- end A;
-
- 21.d with A;
- package B is
- package A_View renames A;
- function F_View(X : Integer := 9999) return Boolean renames F;
- end B;
-
- 21.e with A, B; use A, B;
- procedure Main is ...
-
- 21.f Within Main, the expressions ``F'', ``A.F'', ``B.A_View.F'', and
- ``A_View.F'' are all fully conformant with one another.
- However, ``F'' and ``F_View'' are not fully conformant. If they
- were, it would be bad news, since the two denoted views have
- different default_expressions.
-
- 22 each primary that is a literal in one has the same value as the
- corresponding literal in the other.
-
- 22.a Ramification: The literals may be written differently.
-
- 22.b Ramification: Note that the above definition makes full
- conformance a transitive relation.
-
- 23 {full conformance (for known_discriminant_parts)} Two known_
- discriminant_parts are fully conformant if they have the same number of
- discriminants, and discriminants in the same positions have the same names,
- statically matching subtypes, and default_expressions that are fully
- conformant with one another. {statically matching [required]}
-
- 24 {full conformance (for discrete_subtype_definitions)} Two discrete_
- subtype_definitions are fully conformant if they are both subtype_indications
- or are both ranges, the subtype_marks (if any) denote the same subtype, and
- the corresponding simple_expressions of the ranges (if any) fully conform.
-
- 24.a Ramification: In the subtype_indication case, any ranges have
- to be corresponding; that is, two subtype_indications cannot conform
- unless both or neither has a range.
-
- 24.b Discussion: This definition is used in 9.5.2, ``Entries and
- Accept Statements'' for the conformance required between the
- discrete_subtype_definitions of an entry_declaration for a family of
- entries and the corresponding entry_index_specification of the entry_
- body.
-
-
- Implementation Permissions
-
- 25 An implementation may declare an operator declared in a language-defined
- library unit to be intrinsic.
-
-
- Extensions to Ada 83
-
- 25.a {extensions to Ada 83} The rules for full conformance are
- relaxed -- they are now based on the structure of constructs, rather
- than the sequence of lexical elements. This implies, for example,
- that "(X, Y: T)" conforms fully with "(X: T; Y: T)", and "(X: T)"
- conforms fully with "(X: in T)". {94-4718.c}
-
-
-
- 6.3.2 Inline Expansion of Subprograms
-
- 1 [Subprograms may be expanded in line at the call site.]
-
-
- Syntax
-
- 2 {program unit pragma [Inline]} {pragma, program unit [Inline]} The
- form of a pragma Inline, which is a program unit pragma (see 10.1.5), is
- as follows:
-
-
- 3 pragma Inline(name {, name});
-
-
- Legality Rules
-
- 4 The pragma shall apply to one or more callable entities or generic
- subprograms.
-
-
- Static Semantics
-
- 5 If a pragma Inline applies to a callable entity, this indicates that
- inline expansion is desired for all calls to that entity. If a pragma Inline
- applies to a generic subprogram, this indicates that inline expansion is
- desired for all calls to all instances of that generic subprogram.
-
- 5.a Ramification: Note that inline expansion is desired no matter
- what name is used in the call. This allows one to request inlining
- for only one of several overloaded subprograms as follows:
-
- 5.b package IO is
- procedure Put(X : in Integer);
- procedure Put(X : in String);
- procedure Put(X : in Character);
- private
- procedure Character_Put(X : in Character) renames Put;
- pragma Inline(Character_Put);
- end IO;
-
- 5.c with IO; use IO;
- procedure Main is
- I : Integer;
- C : Character;
- begin
- ...
- Put(C); -- Inline expansion is desired.
- Put(I); -- Inline expansion is NOT desired.
- end Main;
-
- 5.d Ramification: The meaning of a subprogram can be changed by a
- pragma Inline only in the presence of failing checks (see 11.6).
- Implementation Permissions
-
- 6 For each call, an implementation is free to follow or to ignore the
- recommendation expressed by the pragma.
-
- 6.a Ramification: Note, in particular, that the recommendation
- cannot always be followed for a recursive call, and is often
- infeasible for entries. Note also that the implementation can inline
- calls even when no such desire was expressed by a pragma, so long as
- the semantics of the program remains unchanged. {94-4477.a}
-
-
- NOTES
- 7 (6) The name in a pragma Inline can denote more than one entity in the
- case of overloading. Such a pragma applies to all of the denoted
- entities.
-
-
- Extensions to Ada 83
-
- 7.a {extensions to Ada 83} A pragma Inline is allowed inside a
- subprogram_body if there is no corresponding subprogram_declaration.
- This is for uniformity with other program unit pragmas.
-
-
-
- 6.4 Subprogram Calls
-
- 1 {subprogram call} A subprogram call is either a procedure_call_statement
- or a function_call; [it invokes the execution of the subprogram_body. The
- call specifies the association of the actual parameters, if any, with formal
- parameters of the subprogram.]
-
-
- Syntax
-
- 2 procedure_call_statement ::=
- procedure_name;
- | procedure_prefix actual_parameter_part;
-
- 3 function_call ::=
- function_name
- | function_prefix actual_parameter_part
-
- 4 actual_parameter_part ::=
- (parameter_association {, parameter_association})
-
- 5 parameter_association ::=
- [formal_parameter_selector_name =>] explicit_actual_parameter
-
- 6 explicit_actual_parameter ::= expression | variable_name
-
- 7 {named association} {positional association} A parameter_association
- is named or positional according to whether or not the formal_
- parameter_selector_name is specified. Any positional associations shall
- precede any named associations. Named associations are not allowed if
- the prefix in a subprogram call is an attribute_reference.
-
- 7.a Ramification: This means that the formal parameter names used
- in describing predefined attributes are to aid presentation of their
- semantics, but are not intended for use in actual calls.
-
-
- Name Resolution Rules
-
- 8 The name or prefix given in a procedure_call_statement shall resolve to
- denote a callable entity that is a procedure, or an entry renamed as (viewed
- as) a procedure. The name or prefix given in a function_call shall resolve
- to denote a callable entity that is a function. [When there is an actual_
- parameter_part, the prefix can be an implicit_dereference of an
- access-to-subprogram value.]
-
- 8.a Ramification: The function can be an operator, enumeration
- literal, attribute that is a function, etc.
-
- 9 A subprogram call shall contain at most one association for each formal
- parameter. Each formal parameter without an association shall have a
- default_expression (in the profile of the view denoted by the name or
- prefix). This rule is an overloading rule (see 8.6).
-
-
- Dynamic Semantics
-
- 10 {execution [subprogram call]} For the execution of a subprogram call,
- the name or prefix of the call is evaluated, and each parameter_association
- is evaluated (see 6.4.1). If a default_expression is used, an implicit
- parameter_association is assumed for this rule. These evaluations are done
- in an arbitrary order. The subprogram_body is then executed. Finally, if
- the subprogram completes normally, then after it is left, any necessary
- assigning back of formal to actual parameters occurs (see 6.4.1).
-
- 10.a Discussion: The implicit association for a default is only
- for this run-time rule. At compile time, the visibility rules are
- applied to the default at the place where it occurs, not at the place
- of a call.
-
- 10.b To be honest: If the subprogram is inherited, see 3.4,
- ``Derived Types and Classes''.
-
- 10.c If the subprogram is protected, see 9.5.1, ``Protected
- Subprograms and Protected Actions''.
-
- 10.d If the subprogram is really a renaming of an entry, see 9.5.3,
- ``Entry Calls''.
-
- 10.e Normally, the subprogram_body that is executed by the above
- rule is the one for the subprogram being called. For an enumeration
- literal, implicitly declared (but noninherited) subprogram, or an
- attribute that is a subprogram, an implicit body is assumed. For a
- dispatching call, 3.9.2, ``Dispatching Operations of Tagged Types''
- defines which subprogram_body is executed.
-
- 11 {Program_Error (raised by failure of run-time check)} The exception
- Program_Error is raised at the point of a function_call if the function
- completes normally without executing a return_statement.
-
- 11.a Discussion: We are committing to raising the exception at the
- point of call, for uniformity -- see AI-00152. This happens after
- the function is left, of course.
-
- 11.b Note that there is no name for suppressing this check, since
- the check imposes no time overhead and minimal space overhead (since
- it can usually be statically eliminated as dead code).
-
- 12 A function_call denotes a constant, as defined in 6.5; the nominal
- subtype of the constant is given by the result subtype of the function.
- {nominal subtype [of the result of a function_call]} {constant [result of a
- function_call]}
-
-
- Examples
-
- 13 Examples of procedure calls:
-
- 14 Traverse_Tree; -- see 6.1
- Print_Header(128, Title, True); -- see 6.1
-
- 15 Switch(From => X, To => Next); -- see 6.1
- Print_Header(128, Header => Title, Center => True); -- see 6.1
- Print_Header(Header => Title, Center => True, Pages => 128); -- see 6.1
-
- 16 Examples of function calls:
-
- 17 Dot_Product(U, V) -- see 6.1 and 6.3
- Clock -- see 9.6
- F.all -- presuming F is of an access-to-subprogram type -- s\
- ee 3.10
-
- 18 Examples of procedures with default expressions:
-
- 19 procedure Activate(Process : in Process_Name;
- After : in Process_Name := No_Process;
- Wait : in Duration := 0.0;
- Prior : in Boolean := False);
-
- 20 procedure Pair(Left, Right : in Person_Name := new Person); -- see 3.10.1
-
- 21 Examples of their calls:
-
- 22 Activate(X);
- Activate(X, After => Y);
- Activate(X, Wait => 60.0, Prior => True);
- Activate(X, Y, 10.0, False);
-
- 23 Pair;
- Pair(Left => new Person, Right => new Person);
-
-
- NOTES
- 24 (7) If a default_expression is used for two or more parameters in a
- multiple parameter_specification, the default_expression is evaluated
- once for each omitted parameter. Hence in the above examples, the two
- calls of Pair are equivalent.
-
-
- Examples
-
- 25 Examples of overloaded subprograms:
-
- 26 procedure Put(X : in Integer);
- procedure Put(X : in String);
-
- 27 procedure Set(Tint : in Color);
- procedure Set(Signal : in Light);
-
- 28 Examples of their calls:
-
- 29 Put(28);
- Put("no possible ambiguity here");
-
- 30 Set(Tint => Red);
- Set(Signal => Red);
- Set(Color'(Red));
-
- 31 -- Set(Red) would be ambiguous since Red may
- -- denote a value either of type Color or of type Light
-
-
- Wording Changes From Ada 83
- 31.a We have gotten rid of parameters ``of the form of a type
- conversion'' (see RM83-6.4.1(3)). The new view semantics of type_
- conversions allows us to use normal type_conversions instead.
-
- 31.b We have moved wording about run-time semantics of parameter
- associations to 6.4.1.
-
- 31.c We have moved wording about raising Program_Error for a
- function that falls off the end to here from RM83-6.5.
-
-
-
- 6.4.1 Parameter Associations
-
- 1 [{parameter passing} A parameter association defines the association
- between an actual parameter and a formal parameter.]
-
-
- Language Design Principles
-
- 1.a The parameter passing rules for out parameters are designed to
- ensure that the parts of a type that have implicit initial values
- (see 3.3.1) don't become ``de-initialized'' by being passed as an out
- parameter.
-
- Name Resolution Rules
-
- 2 The formal_parameter_selector_name of a parameter_association shall
- resolve to denote a parameter_specification of the view being called.
-
- 3 {actual parameter (for a formal parameter)} The actual parameter is
- either the explicit_actual_parameter given in a parameter_association for a
- given formal parameter, or the corresponding default_expression if no
- parameter_association is given for the formal parameter. {expected type
- (actual parameter)} The expected type for an actual parameter is the type of
- the corresponding formal parameter.
-
- 3.a To be honest: The corresponding default_expression is the one
- of the corresponding formal parameter in the profile of the view
- denoted by the name or prefix of the call.
-
- 4 If the mode is in, the actual is interpreted as an expression; otherwise,
- the actual is interpreted only as a name, if possible.
-
- 4.a Ramification: This formally resolves the ambiguity present in
- the syntax rule for explicit_actual_parameter. Note that we don't
- actually require that the actual be a name if the mode is not in; we
- do that below.
-
-
- Legality Rules
-
- 5 If the mode is in out or out, the actual shall be a name that denotes a
- variable.
-
- 5.a Discussion: We no longer need ``or a type_conversion whose
- argument is the name of a variable,'' because a type_conversion is
- now a name, and a type_conversion of a variable is a variable.
-
- 5.b Reason: The requirement that the actual be a (variable) name
- is not an overload resolution rule, since we don't want the
- difference between expression and name to be used to resolve
- overloading. For example:
-
- 5.c procedure Print(X : in Integer; Y : in Boolean := True);
- procedure Print(Z : in out Integer);
- . . .
- Print(3); -- Ambiguous!
-
- 5.d The above call to Print is ambiguous even though the call is
- not compatible with the second Print which requires an actual that is
- a (variable) name (``3'' is an expression, not a name). This
- requirement is a legality rule, so overload resolution fails before
- it is considered, meaning that the call is ambiguous.
-
- 6 The type of the actual parameter associated with an access parameter
- shall be convertible (see 4.6) to its anonymous access type. {convertible
- [required]}
-
-
- Dynamic Semantics
-
- 7 {evaluation [parameter_association]} For the evaluation of a parameter_
- association:
-
- 8 The actual parameter is first evaluated.
-
- 9 For an access parameter, the access_definition is elaborated,
- which creates the anonymous access type.
-
- 10 For a parameter [(of any mode)] that is passed by reference (see
- 6.2), a view conversion of the actual parameter to the nominal
- subtype of the formal parameter is evaluated, and the formal
- parameter denotes that conversion. {implicit subtype conversion
- [parameter passing]}
-
- 10.a Discussion: We are always allowing sliding, even for [in] out
- by-reference parameters.
-
- 11 {assignment operation (during evaluation of a parameter_
- association)} For an in or in out parameter that is passed by
- copy (see 6.2), the formal parameter object is created, and the
- value of the actual parameter is converted to the nominal subtype
- of the formal parameter and assigned to the formal. {implicit
- subtype conversion [parameter passing]}
-
- 11.a Ramification: The conversion mentioned here is a value
- conversion.
-
- 12 For an out parameter that is passed by copy, the formal parameter
- object is created, and:
-
- 13 For an access type, the formal parameter is initialized
- from the value of the actual, without a constraint check;
-
- 13.a Reason: This preserves the Language Design Principle that an
- object of an access type is always initialized with a
- ``reasonable'' value.
-
- 14 For a composite type with discriminants or that has
- implicit initial values for any subcomponents (see 3.3.1),
- the behavior is as for an in out parameter passed by copy.
- {94-4783.a} {94-4785.a}
-
- 14.a Reason: This ensures that no part of an object of such a type
- can become ``de-initialized'' by being part of an out parameter.
- {94-4783.b}
-
- 14.b Ramification: This includes an array type whose component type
- is an access type, and a record type with a component that has a
- default_expression, among other things.
-
- 15 For any other type, the formal parameter is uninitialized.
- If composite, a view conversion of the actual parameter to
- the nominal subtype of the formal is evaluated [(which
- might raise Constraint_Error)], and the actual subtype of
- the formal is that of the view conversion. If elementary,
- the actual subtype of the formal is given by its nominal
- subtype.
-
- 15.a Ramification: This case covers scalar types, and composite
- types whose subcomponent's subtypes do not have any implicit
- initial values. The view conversion for composite types ensures
- that if the lengths don't match between an actual and a formal
- array parameter, the Constraint_Error is raised before the call,
- rather than after.
-
- 16 {constrained [object]} {unconstrained [object]} A formal parameter of
- mode in out or out with discriminants is constrained if either its nominal
- subtype or the actual parameter is constrained.
-
- 17 {parameter copy back} {copy back of parameters} {parameter assigning
- back} {assigning back of parameters} {assignment operation (during parameter
- copy back)} After normal completion and leaving of a subprogram, for each in
- out or out parameter that is passed by copy, the value of the formal
- parameter is converted to the subtype of the variable given as the actual
- parameter and assigned to it. {implicit subtype conversion [parameter
- passing]} These conversions and assignments occur in an arbitrary order.
-
- 17.a Ramification: The conversions mentioned above during
- parameter passing might raise Constraint_Error -- (see 4.6).
-
- 17.b Ramification: If any conversion or assignment as part of
- parameter passing propagates an exception, the exception is raised at
- the place of the subprogram call; that is, it cannot be handled
- inside the subprogram_body.
-
- 17.c Proof: Since these checks happen before or after executing
- the subprogram_body, the execution of the subprogram_body does not
- dynamically enclose them, so it can't handle the exceptions.
-
- 17.d Discussion: The variable we're talking about is the one
- denoted by the variable_name given as the explicit_actual_parameter.
- If this variable_name is a type_conversion, then the rules in 4.6 for
- assigning to a view conversion apply. That is, if X is of subtype
- S1, and the actual is S2(X), the above-mentioned conversion will
- convert to S2, and the one mentioned in 4.6 will convert to S1.
-
-
- Extensions to Ada 83
-
- 17.e {extensions to Ada 83} In Ada 9X, a program can rely on the
- fact that passing an object as an out parameter does not
- ``de-initialize'' any parts of the object whose subtypes have
- implicit initial values. (This generalizes the RM83 rule that
- required copy-in for parts that were discriminants or of an access
- type.)
-
- Wording Changes From Ada 83
-
- 17.f We have eliminated the subclause on Default Parameters, as it
- is subsumed by earlier clauses and subclauses.
-
-
-
- 6.5 Return Statements
-
- 1 A return_statement is used to complete the execution of the innermost
- enclosing subprogram_body, entry_body, or accept_statement.
- Syntax
-
- 2 return_statement ::= return [expression];
-
-
- Name Resolution Rules
-
- 3 {return expression} The expression, if any, of a return_statement is
- called the return expression. {result subtype (of a function)} The result
- subtype of a function is the subtype denoted by the subtype_mark after the
- reserved word return in the profile of the function. {expected type [return
- expression]} The expected type for a return expression is the result type of
- the corresponding function.
-
- 3.a To be honest: The same applies to generic functions.
-
-
- Legality Rules
-
- 4 {apply (to a callable construct by a return_statement)} A return_
- statement shall be within a callable construct, and it applies to the
- innermost one. A return_statement shall not be within a body that is within
- the construct to which the return_statement applies.
-
- 5 A function body shall contain at least one return_statement that applies
- to the function body, unless the function contains code_statements. A
- return_statement shall include a return expression if and only if it applies
- to a function body.
-
- 5.a Reason: The requirement that a function body has to have at
- least one return_statement is a ``helpful'' restriction. There was
- been some interest in lifting this restriction, or allowing a raise
- statement to substitute for the return_statement. However, there was
- enough interest in leaving it as is that we decided not to change it.
-
-
- Dynamic Semantics
-
- 6 {execution [return_statement]} For the execution of a return_statement,
- the expression (if any) is first evaluated and converted to the result
- subtype. {implicit subtype conversion [function return]}
-
- 6.a Ramification: The conversion might raise Constraint_Error --
- (see 4.6).
-
- 7 If the result type is class-wide, then the tag of the result is the tag
- of the value of the expression.
-
- 8 If the result type is a specific tagged type:
-
- 9 {Tag_Check [partial]} {check, language-defined (Tag_Check)} If it
- is limited, then a check is made that the tag of the value of the
- return expression identifies the result type. {Constraint_Error
- (raised by failure of run-time check)} Constraint_Error is raised
- if this check fails.
-
- 10 If it is nonlimited, then the tag of the result is that of the
- result type.
-
- 10.a Ramification: This is true even if the tag of the return
- expression is different.
-
- 10.b Reason: These rules ensure that a function whose result type is
- a specific tagged type always returns an object whose tag is
- that of the result type. This is important for dispatching on
- controlling result, and, if nonlimited, allows the caller to
- allocate the appropriate amount of space to hold the value being
- returned (assuming there are no discriminants).
-
- 11 {return-by-reference type} A type is a return-by-reference type if it is
- a descendant of one of the following:
-
- 12 a tagged limited type;
-
- 13 a task or protected type;
-
- 14 a nonprivate type with the reserved word limited in its
- declaration;
-
- 15 a composite type with a subcomponent of a return-by-reference
- type;
-
- 16 a private type whose full type is a return-by-reference type.
-
- 16.a Ramification: The above rules are such that there are no "Ada
- 83" types other than those containing tasks that are return-by-
- reference. This helps to minimize upward incompatibilities relating
- to return-by-reference.
-
- 17 {Accessibility_Check [partial]} {check, language-defined (Accessibility_
- Check)} If the result type is a return-by-reference type, then a check is
- made that the return expression is one of the following:
-
- 18 a name that denotes an object view whose accessibility level is
- not deeper than that of the master that elaborated the function
- body; or
-
- 19 a parenthesized expression or qualified_expression whose operand
- is one of these kinds of expressions. {94-4715.a}
-
- 20 {Program_Error (raised by failure of run-time check)} The exception
- Program_Error is raised if this check fails.
-
- 20.a Discussion: Compare the definition of return-by-reference
- with that of by-reference.
-
- 20.b The return-by-reference types are all limited types except
- those that are limited only because of a limited private type with a
- nonlimited untagged full type.
-
- 20.c Reason: {generic contract issue [partial]}
-
- 20.d This check can often be performed at compile time. It is
- defined to be a run-time check to avoid generic contract model
- problems. In a future version of the standard, we anticipate that
- function return of a local variable will be illegal for all limited
- types, eliminating the need for the run-time check except for
- dereferences of an access parameter.
-
- 21 For a function with a return-by-reference result type the result is
- returned by reference; that is, the function call denotes a constant view of
- the object associated with the value of the return expression. {assignment
- operation (during execution of a return_statement)} For any other function,
- the result is returned by copy; that is, the converted value is assigned into
- an anonymous constant created at the point of the return_statement, and the
- function call denotes that object.
-
- 21.a Ramification: The assignment operation does the necessary
- value adjustment, as described in 7.6, ``User-Defined Assignment and
- Finalization''. 7.6.1 describes when the anonymous constant is
- finalized.
-
- 22 Finally, a transfer of control is performed which completes the
- execution of the callable construct to which the return_statement applies,
- and returns to the caller.
-
-
- Examples
-
- 23 Examples of return statements:
-
- 24 return; -- in a procedure body, entry_body, or acce\
- pt_statement
- return Key_Value(Last_Index); -- in a function body
-
-
- Incompatibilities With Ada 83
-
- 24.a {incompatibilities with Ada 83} In Ada 9X, if the result type
- of a function has a part that is a task, then an attempt to return a
- local variable will raise Program_Error. In Ada 83, if a function
- returns a local variable containing a task, execution is erroneous
- according to AI-00867. However, there are other situations where
- functions that return tasks (or that return a variant record only one
- of whose variants includes a task) are correct in Ada 83 but will
- raise Program_Error according to the new rules.
-
- 24.b The rule change was made because there will be more types
- (protected types, limited controlled types) in Ada 9X for which it
- will be meaningless to return a local variable, and making all of
- these erroneous is unacceptable. The current rule was felt to be the
- simplest that kept upward incompatibilities to situations involving
- returning tasks, which are quite rare.
-
- Wording Changes From Ada 83
-
- 24.c This clause has been moved here from chapter 5, since it has
- mainly to do with subprograms.
-
- 24.d A function now creates an anonymous object. This is necessary
- so that controlled types will work.
-
- 24.e We have clarified that a return_statement applies to a
- callable construct, not to a callable entity.
-
- 24.f There is no need to mention generics in the rules about where
- a return_statement can appear and what it applies to; the phrase
- ``body of a subprogram or generic subprogram'' is syntactic, and
- refers exactly to ``subprogram_body''.
-
-
-
- 6.6 Overloading of Operators
-
- 1 {operator} {user-defined operator} {operator (user-defined)} An operator
- is a function whose designator is an operator_symbol. [Operators, like other
- functions, may be overloaded.]
-
-
- Name Resolution Rules
-
- 2 Each use of a unary or binary operator is equivalent to a function_call
- with function_prefix being the corresponding operator_symbol, and with
- (respectively) one or two positional actual parameters being the operand(s)
- of the operator (in order).
-
- 2.a To be honest: We also use the term operator (in Section 4 and
- in 6.1) to refer to one of the syntactic categories defined in 4.5,
- ``Operators and Expression Evaluation'' whose names end with
- ``_operator:'' logical_operator, relational_operator, binary_adding_
- operator, unary_adding_operator, multiplying_operator, and highest_
- precedence_operator.
-
-
- Legality Rules
-
- 3 The subprogram_specification of a unary or binary operator shall have one
- or two parameters, respectively. A generic function instantiation whose
- designator is an operator_symbol is only allowed if the specification of the
- generic function has the corresponding number of parameters.
-
- 4 Default_expressions are not allowed for the parameters of an operator
- (whether the operator is declared with an explicit subprogram_specification
- or by a generic_instantiation).
-
- 5 An explicit declaration of "/=" shall not have a result type of the
- predefined type Boolean.
-
-
- Static Semantics
-
- 6 A declaration of "=" whose result type is Boolean implicitly declares a
- declaration of "/=" that gives the complementary result. {94-4701.a}
-
-
- NOTES
- 7 (8) The operators "+" and "-" are both unary and binary operators, and
- hence may be overloaded with both one- and two-parameter functions.
-
-
- Examples
-
- 8 Examples of user-defined operators:
-
- 9 function "+" (Left, Right : Matrix) return Matrix;
- function "+" (Left, Right : Vector) return Vector;
-
- -- assuming that A, B, and C are of the type Vector
- -- the following two statements are equivalent:
-
- A := B + C;
- A := "+"(B, C);
-
-
- Extensions to Ada 83
-
- 9.a {extensions to Ada 83} Explicit declarations of "=" are now
- permitted for any combination of parameter and result types.
-
- 9.b Explicit declarations of "/=" are now permitted, so long as the
- result type is not Boolean.
-
-
-
- Section 7: Packages
-
-
- 1 [{Package} [glossary entry]Packages are program units that allow the
- specification of groups of logically related entities. Typically, a package
- contains the declaration of a type (often a private type or private
- extension) along with the declarations of primitive subprograms of the type,
- which can be called from outside the package, while their inner workings
- remain hidden from outside users.{information hiding: see package}
- {encapsulation: see package} {module: see package} {class: see also package}]
-
-
-
- 7.1 Package Specifications and Declarations
-
- 1 [A package is generally provided in two parts: a package_specification
- and a package_body. Every package has a package_specification, but not all
- packages have a package_body.]
-
-
- Syntax
-
- 2 package_declaration ::= package_specification;
-
- 3 package_specification ::=
- package defining_program_unit_name is
- {basic_declarative_item}
- [private
- {basic_declarative_item}]
- end [[parent_unit_name.]identifier]
-
- 4 If an identifier or parent_unit_name.identifier appears at the end of
- a package_specification, then this sequence of lexical elements shall
- repeat the defining_program_unit_name.
-
-
- Legality Rules
-
- 5 {requires a completion [package_declaration]} {requires a completion
- [generic_package_declaration]} A package_declaration or generic_package_
- declaration requires a completion [(a body)] if it contains any declarative_
- item that requires a completion, but whose completion is not in its package_
- specification.
-
- 5.a To be honest: If an implementation supports it, a pragma
- Import may substitute for the body of a package or generic package.
-
-
- Static Semantics
-
- 6 {visible part [of a package (other than a generic formal package)]} The
- first list of declarative_items of a package_specification of a package other
- than a generic formal package is called the visible part of the package.
- [{private part [of a package]} The optional list of declarative_items after
- the reserved word private (of any package_specification) is called the
- private part of the package. If the reserved word private does not appear,
- the package has an implicit empty private part.]
-
- 6.a Ramification: This definition of visible part does not apply
- to generic formal packages -- 12.7 defines the visible part of a
- generic formal package.
-
- 6.b The implicit empty private part is important because certain
- implicit declarations occur there if the package is a child package,
- and it defines types in its visible part that are derived from, or
- contain as components, private types declared within the parent
- package. These implicit declarations are visible in children of the
- child package. See 10.1.1.
-
- 7 [An entity declared in the private part of a package is visible only
- within the declarative region of the package itself (including any child
- units -- see 10.1.1). In contrast, expanded names denoting entities declared
- in the visible part can be used even outside the package; furthermore, direct
- visibility of such entities can be achieved by means of use_clauses (see
- 4.1.3 and 8.4).]
-
-
- Dynamic Semantics
-
- 8 {elaboration [package_declaration]} The elaboration of a package_
- declaration consists of the elaboration of its basic_declarative_items in the
- given order.
-
-
- NOTES
- 9 (1) The visible part of a package contains all the information that
- another program unit is able to know about the package.
-
- 10 (2) If a declaration occurs immediately within the specification of a
- package, and the declaration has a corresponding completion that is a
- body, then that body has to occur immediately within the body of the
- package.
-
- 10.a Proof: This follows from the fact that the declaration and
- completion are required to occur immediately within the same
- declarative region, and the fact that bodies are disallowed (by the
- Syntax Rules) in package_specifications. This does not apply to
- instances of generic units, whose bodies can occur in package_
- specifications.
-
-
- Examples
-
- 11 Example of a package declaration:
-
- 12 package Rational_Numbers is
-
- 13 type Rational is
- record
- Numerator : Integer;
- Denominator : Positive;
- end record;
-
- 14 function "="(X,Y : Rational) return Boolean;
-
- 15 function "/" (X,Y : Integer) return Rational; -- to construct a rati\
- onal number
-
- 16 function "+" (X,Y : Rational) return Rational;
- function "-" (X,Y : Rational) return Rational;
- function "*" (X,Y : Rational) return Rational;
- function "/" (X,Y : Rational) return Rational;
- end Rational_Numbers;
-
- 17 There are also many examples of package declarations in the predefined
- language environment (see Annex A).
-
-
- Incompatibilities With Ada 83
-
- 17.a {incompatibilities with Ada 83} In Ada 83, a library package
- is allowed to have a body even if it doesn't need one. In Ada 9X, a
- library package body is either required or forbidden -- never
- optional. The workaround is to add pragma Elaborate_Body, or
- something else requiring a body, to each library package that has a
- body that isn't otherwise required.
-
- Wording Changes From Ada 83
-
- 17.b We have moved the syntax into this clause and the next clause
- from RM83-7.1, ``Package Structure'', which we have removed.
-
- 17.c RM83 was unclear on the rules about when a package requires a
- body. For example, RM83-7.1(4) and RM83-7.1(8) clearly forgot about
- the case of an incomplete type declared in a package_declaration but
- completed in the body. In addition, RM83 forgot to make this rule
- apply to a generic package. We have corrected these rules. Finally,
- since we now allow a pragma Import for any explicit declaration, the
- completion rules need to take this into account as well.
-
-
-
- 7.2 Package Bodies
-
- 1 [In contrast to the entities declared in the visible part of a package,
- the entities declared in the package_body are visible only within the
- package_body itself. As a consequence, a package with a package_body can be
- used for the construction of a group of related subprograms in which the
- logical operations available to clients are clearly isolated from the
- internal entities.]
-
-
- Syntax
-
- 2 package_body ::=
- package body defining_program_unit_name is
- declarative_part
- [begin
- handled_sequence_of_statements]
- end [[parent_unit_name.]identifier];
-
- 3 If an identifier or parent_unit_name.identifier appears at the end of
- a package_body, then this sequence of lexical elements shall repeat the
- defining_program_unit_name.
-
-
- Legality Rules
-
- 4 A package_body shall be the completion of a previous package_declaration
- or generic_package_declaration. A library package_declaration or library
- generic_package_declaration shall not have a body unless it requires a body[;
- pragma Elaborate_Body can be used to require a library_unit_declaration to
- have a body (see 10.2.1) if it would not otherwise require one]. {94-4409.a}
-
- 4.a Ramification: The first part of the rule forbids a package_
- body from standing alone -- it has to belong to some previous
- package_declaration or generic_package_declaration.
-
- 4.b A nonlibrary package_declaration or nonlibrary generic_package_
- declaration that does not require a completion may have a
- corresponding body anyway.
-
-
- Static Semantics
-
- 5 In any package_body without statements there is an implicit null_
- statement. For any package_declaration without an explicit completion, there
- is an implicit package_body containing a single null_statement. For a
- noninstance, nonlibrary package, this body occurs at the end of the
- declarative_part of the innermost enclosing program unit or block_statement;
- if there are several such packages, the order of the implicit package_bodies
- is unspecified. {unspecified [partial]} [(For an instance, the implicit
- package_body occurs at the place of the instantiation (see 12.3). For a
- library package, the place is partially determined by the elaboration
- dependences (see Section 10).)]
-
- 5.a Discussion: Thus, for example, we can refer to something
- happening just after the begin of a package_body, and we can refer to
- the handled_sequence_of_statements of a package_body, without
- worrying about all the optional pieces. The place of the implicit
- body makes a difference for tasks activated by the package. See also
- RM83-9.3(5).
-
- 5.b The implicit body would be illegal if explicit in the case of a
- library package that does not require (and therefore does not allow)
- a body. This is a bit strange, but not harmful.
-
-
- Dynamic Semantics
-
- 6 {elaboration [nongeneric package_body]} For the elaboration of a
- nongeneric package_body, its declarative_part is first elaborated, and its
- handled_sequence_of_statements is then executed.
-
-
- NOTES
- 7 (3) A variable declared in the body of a package is only visible within
- this body and, consequently, its value can only be changed within the
- package_body. In the absence of local tasks, the value of such a
- variable remains unchanged between calls issued from outside the package
- to subprograms declared in the visible part. The properties of such a
- variable are similar to those of a ``static'' variable of C.
-
- 8 (4) The elaboration of the body of a subprogram explicitly declared in
- the visible part of a package is caused by the elaboration of the body
- of the package. Hence a call of such a subprogram by an outside program
- unit raises the exception Program_Error if the call takes place before
- the elaboration of the package_body (see 3.11).
-
-
- Examples
-
- 9 Example of a package body (see 7.1):
-
- 10 package body Rational_Numbers is
-
- 11 procedure Same_Denominator (X,Y : in out Rational) is
- begin
- -- reduces X and Y to the same denominator:
- ...
- end Same_Denominator;
-
- 12 function "="(X,Y : Rational) return Boolean is
- U : Rational := X;
- V : Rational := Y;
- begin
- Same_Denominator (U,V);
- return U.Numerator = V.Numerator;
- end "=";
-
- 13 function "/" (X,Y : Integer) return Rational is
- begin
- if Y > 0 then
- return (Numerator => X, Denominator => Y);
- else
- return (Numerator => -X, Denominator => -Y);
- end if;
- end "/";
-
- 14 function "+" (X,Y : Rational) return Rational is ... end "+";
- function "-" (X,Y : Rational) return Rational is ... end "-";
- function "*" (X,Y : Rational) return Rational is ... end "*";
- function "/" (X,Y : Rational) return Rational is ... end "/";
-
- 15 end Rational_Numbers;
-
-
- Wording Changes From Ada 83
-
- 15.a The syntax rule for package_body now uses the syntactic
- category handled_sequence_of_statements.
-
- 15.b The declarative_part of a package_body is now required; that
- doesn't make any real difference, since a declarative_part can be
- empty.
-
- 15.c RM83 seems to have forgotten to say that a package_body can't
- stand alone, without a previous declaration. We state that rule
- here.
-
- 15.d RM83 forgot to restrict the definition of elaboration of
- package_bodies to nongeneric ones. We have corrected that omission.
-
- 15.e The rule about implicit bodies (from RM83-9.3(5)) is moved
- here, since it is more generally applicable.
-
-
-
- 7.3 Private Types and Private Extensions
-
- 1 [The declaration (in the visible part of a package) of a type as a
- private type or private extension serves to separate the characteristics that
- can be used directly by outside program units (that is, the logical
- properties) from other characteristics whose direct use is confined to the
- package (the details of the definition of the type itself). See 3.9.1 for an
- overview of type extensions. {private types and private extensions}
- {information hiding: see private types and private extensions} {opaque type:
- see private types and private extensions} {abstract data type (ADT): see
- private types and private extensions} {ADT (abstract data type): see private
- types and private extensions}]
-
-
- Language Design Principles
-
- 1.a A private (untagged) type can be thought of as a record type
- with the type of its single (hidden) component being the full view.
-
- 1.b A private tagged type can be thought of as a private extension
- of an anonymous parent with no components. The only dispatching
- operation of the parent is equality (although the Size attribute,
- and, if nonlimited, assignment are allowed, and those will presumably
- be implemented in terms of dispatching).
-
- Syntax
-
- 2 private_type_declaration ::=
- type defining_identifier [discriminant_part] is [[abstract] tagged] [lim\
- ited] private;
-
- 3 private_extension_declaration ::=
- type defining_identifier [discriminant_part] is
- [abstract] new ancestor_subtype_indication with private;
-
-
- Legality Rules
-
- 4 {partial view (of a type)} {requires a completion [declaration of a
- partial view]} A private_type_declaration or private_extension_declaration
- declares a partial view of the type; such a declaration is allowed only as a
- declarative_item of the visible part of a package, and it requires a
- completion, which shall be a full_type_declaration that occurs as a
- declarative_item of the private part of the package. {full view (of a type)}
- The view of the type declared by the full_type_declaration is called the full
- view. A generic formal private type or a generic formal private extension is
- also a partial view.
-
- 4.a To be honest: A private type can also be completed by a pragma
- Import, if supported by an implementation.
- 4.b Reason: We originally used the term ``private view,'' but this
- was easily confused with the view provided from the private part,
- namely the full view.
-
- 5 [A type shall be completely defined before it is frozen (see 3.11.1 and
- 13.14). Thus, neither the declaration of a variable of a partial view of a
- type, nor the creation by an allocator of an object of the partial view are
- allowed before the full declaration of the type. Similarly, before the full
- declaration, the name of the partial view cannot be used in a generic_
- instantiation or in a representation item.]
-
- 5.a Proof: This rule is stated officially in 3.11.1, ``Completions
- of Declarations''.
-
- 5.b Change: Rule moved here from 13.14, ``Freezing Rules'', as per
- WG9 resolution.
-
- 6 [A private type is limited if its declaration includes the reserved word
- limited; a private extension is limited if its ancestor type is limited.] If
- the partial view is nonlimited, then the full view shall be nonlimited. If a
- tagged partial view is limited, then the full view shall be limited. [On the
- other hand, if an untagged partial view is limited, the full view may be
- limited or nonlimited.] {94-4662.a} {94-4665.a} {94-4828.b}
-
- 7 If the partial view is tagged, then the full view shall be tagged. [On
- the other hand, if the partial view is untagged, then the full view may be
- tagged or untagged.] In the case where the partial view is untagged and the
- full view is tagged, no derivatives of the partial view are allowed within
- the immediate scope of the partial view; [derivatives of the full view are
- allowed.]
-
- 7.a Ramification: Note that deriving from a partial view within
- its immediate scope can only occur in a package that is a child of
- the one where the partial view is declared. The rule implies that in
- the visible part of a public child package, it is impossible to
- derive from an untagged private type declared in the visible part of
- the parent package in the case where the full view of the parent type
- turns out to be tagged. {94-4443.a} We considered a model in which
- the derived type was implicitly redeclared at the earliest place
- within its immediate scope where characteristics needed to be added.
- However, we rejected that model, because (1) it would imply that (for
- an untagged type) subprograms explicitly declared after the derived
- type could be inherited, and (2) to make this model work for
- composite types as well, several implicit redeclarations would be
- needed, since new characteristics can become visible one by one; that
- seemed like too much mechanism.
-
- 7.b Discussion: The rule for tagged partial views is redundant for
- partial views that are private extensions, since all extensions of a
- given ancestor tagged type are tagged, and limited if the ancestor is
- limited. We phrase this rule partially redundantly to keep its
- structure parallel with the other rules.
-
- 7.c To be honest: This rule is checked in a generic unit, rather
- than using the ``assume the best'' or ``assume the worst'' method.
-
- 7.d Reason: Tagged limited private types have certain capabilities
- that are incompatible with having assignment for the full view of the
- type. In particular, tagged limited private types can be extended
- with access discriminants and components of a limited type, which
- works only because assignment is not allowed. Consider the following
- example:
-
- 7.e package P1 is
- type T1 is tagged limited private;
- procedure Foo(X : in T1'Class);
- private
- type T1 is tagged null record; -- Illegal!
- -- This should say ``tagged limited null record''.
- end P1;
-
- 7.f package body P1 is
- type A is access T1'Class;
- Global : A;
- procedure Foo(X : in T1'Class) is
- begin
- Global := new T1'Class'(X);
- -- This would be illegal if the full view of
- -- T1 were limited, like it's supposed to be.
- end A;
- end P1;
-
- 7.g with P1;
- package P2 is
- type T2(D : access Integer) -- Trouble!
- is new P1.T1 with
- record
- My_Task : Some_Task_Type; -- More trouble!
- end record;
- end P2;
-
- 7.h with P1;
- with P2;
- procedure Main is
- Local : aliased Integer;
- Y : P2.T2(A => Local'Access);
- begin
- P1.Foo(Y);
- end Main;
-
- 7.i If the above example were legal, we would have succeeded in
- making an access value that points to Main.Local after Main has been
- left, and we would also have succeeded in doing an assignment of a
- task object, both of which are supposed to be no-no's.
-
- 7.j This rule is not needed for private extensions, because they
- inherit their limitedness from their ancestor, and there is a
- separate rule forbidding limited components of the corresponding
- record extension if the parent is nonlimited.
-
- 7.k Ramification: A type derived from an untagged private type is
- untagged, even if the full view of the parent is tagged, and even at
- places that can see the parent:
-
- 7.l package P is
- type Parent is private;
- private
- type Parent is tagged
- record
- X: Integer;
- end record;
- end P;
-
- 7.m package Q is
- type T is new Parent;
- end Q;
-
- 7.n with Q; use Q;
- package body P is
- ... T'Class ... -- Illegal!
- Object: T;
- ... Object.X ... -- Illegal!
- ... Parent(Object).X ... -- OK.
- end P;
-
- 7.o The declaration of T declares an untagged view. This view is
- always untagged, so T'Class is illegal, it would be illegal to extend
- T, and so forth. The component name X is never visible for this
- view, although the component is still there -- one can get one's
- hands on it via a type_conversion. {94-4941.a} {94-4946.a}
- {94-5001.g}
-
- 8 {ancestor subtype (of a private_extension_declaration)} The ancestor
- subtype of a private_extension_declaration is the subtype defined by the
- ancestor_subtype_indication; the ancestor type shall be a specific tagged
- type. The full view of a private extension shall be derived (directly or
- indirectly) from the ancestor type. In addition to the places where Legality
- Rules normally apply (see 12.3), the requirement that the ancestor be
- specific applies also in the private part of an instance of a generic unit.
-
- 8.a Reason: This rule allows the full view to be defined through
- several intermediate derivations, possibly from a series of types
- produced by generic_instantiations.
-
- 9 If the declaration of a partial view includes a known_discriminant_part,
- then the full_type_declaration shall have a fully conforming [(explicit)]
- known_discriminant_part [(see 6.3.1, ``Conformance Rules'')]. {full
- conformance (required)} [The ancestor subtype may be unconstrained; the
- parent subtype of the full view is required to be constrained (see 3.7).]
-
- 9.a Discussion: If the ancestor subtype has discriminants, then it
- is usually best to make it unconstrained.
-
- 9.b Ramification: If the partial view has a known_discriminant_
- part, then the full view has to be a composite, non-array type, since
- only such types may have known discriminants. {94-4493.c} Also, the
- full view cannot inherit the discriminants in this case; the known_
- discriminant_part has to be explicit.
-
- 9.c That is, the following is illegal:
-
- 9.d package P is
- type T(D : Integer) is private;
- private
- type T is new Some_Other_Type; -- Illegal!
- end P;
-
- 9.e even if Some_Other_Type has an integer discriminant called D.
-
- 9.f It is a ramification of this and other rules that in order for
- a tagged type to privately inherit unconstrained discriminants, the
- private type declaration has to have an unknown_discriminant_part.
-
- 10 If a private extension inherits known discriminants from the ancestor
- subtype, then the full view shall also inherit its discriminants from the
- ancestor subtype, and the parent subtype of the full view shall be
- constrained if and only if the ancestor subtype is constrained.
-
- 10.a Reason: The first part ensures that the full view has the
- same discriminants as the partial view. The second part ensures that
- if the partial view is unconstrained, then the full view is also
- unconstrained; otherwise, a client might constrain the partial view
- in a way that conflicts with the constraint on the full view.
-
- 11 [If a partial view has unknown discriminants, then the full_type_
- declaration may define a definite or an indefinite subtype, with or without
- discriminants.] {94-4474.a} {94-4886.a}
-
- 12 If a partial view has neither known nor unknown discriminants, then the
- full_type_declaration shall define a definite subtype. {94-4886.a}
- {94-4947.a}
-
- 13 If the ancestor subtype of a private extension has constrained
- discriminants, then the parent subtype of the full view shall impose a
- statically matching constraint on those discriminants. {statically matching
- [required]}
-
- 13.a Ramification: If the parent type of the full view is not the
- ancestor type, but is rather some descendant thereof, the constraint
- on the discriminants of the parent type might come from the
- declaration of some intermediate type in the derivation chain between
- the ancestor type and the parent type.
-
- 13.b Reason: This prevents the following:
-
- 13.c package P is
- type T2 is new T1(Discrim => 3) with private;
- private
- type T2 is new T1(Discrim => 999) -- Illegal!
- with record ...;
- end P;
-
- 13.d The constraints in this example do not statically match.
-
- 13.e If the constraint on the parent subtype of the full view
- depends on discriminants of the full view, then the ancestor subtype
- has to be unconstrained:
-
- 13.f type One_Discrim(A: Integer) is tagged ...;
- ...
- package P is
- type Two_Discrims(B: Boolean; C: Integer) is new One_Discrim wi\
- th private;
- private
- type Two_Discrims(B: Boolean; C: Integer) is new One_Discrim(A \
- => C) with
- record
- ...
- end record;
- end P;
-
- 13.g The above example would be illegal if the private extension
- said ``is new One_Discrim(A => C);'', because then the constraints
- would not statically match. (Constraints that depend on
- discriminants are not static.)
-
-
- Static Semantics
-
- 14 {private type [partial]} A private_type_declaration declares a private
- type and its first subtype. {private extension [partial]} Similarly, a
- private_extension_declaration declares a private extension and its first
- subtype.
-
- 14.a Discussion: {package-private type} A package-private type is
- one declared by a private_type_declaration; that is, a private type
- other than a generic formal private type. {package-private
- extension} Similarly, a package-private extension is one declared by
- a private_extension_declaration. These terms are not used in the
- RM9X version of this document.
-
- 15 A declaration of a partial view and the corresponding full_type_
- declaration define two views of a single type. The declaration of a partial
- view together with the visible part define the operations that are available
- to outside program units; the declaration of the full view together with the
- private part define other operations whose direct use is possible only within
- the declarative region of the package itself. {characteristics} Moreover,
- within the scope of the declaration of the full view, the characteristics of
- the type are determined by the full view; in particular, within its scope,
- the full view determines the classes that include the type, which components,
- entries, and protected subprograms are visible, what attributes and other
- predefined operations are allowed, and whether the first subtype is static.
- See 7.3.1.
-
- 16 A private extension inherits components (including discriminants unless
- there is a new discriminant_part specified) and user-defined primitive
- subprograms from its ancestor type, in the same way that a record extension
- inherits components and user-defined primitive subprograms from its parent
- type (see 3.4).
-
- 16.a To be honest: If an operation of the parent type is abstract,
- then the abstractness of the inherited operation is different for
- nonabstract record extensions than for nonabstract private extensions
- (see 3.9.3).
-
-
- Dynamic Semantics
-
- 17 {elaboration [private_type_declaration]} The elaboration of a private_
- type_declaration creates a partial view of a type. {elaboration [private_
- extension_declaration]} The elaboration of a private_extension_declaration
- elaborates the ancestor_subtype_indication, and creates a partial view of a
- type.
-
-
- NOTES
- 18 (5) The partial view of a type as declared by a private_type_declaration
- is defined to be a composite view (in 3.2). The full view of the type
- might or might not be composite. A private extension is also composite,
- as is its full view.
-
- 19 (6) Declaring a private type with an unknown_discriminant_part is a way
- of preventing clients from creating uninitialized objects of the type;
- they are then forced to initialize each object by calling some operation
- declared in the visible part of the package. If such a type is also
- limited, then no objects of the type can be declared outside the scope
- of the full_type_declaration, restricting all object creation to the
- package defining the type. This allows complete control over all
- storage allocation for the type. Objects of such a type can still be
- passed as parameters, however.
-
- 19.a Discussion: {generic contract/private type contract analogy}
- Packages with private types are analogous to generic packages with
- formal private types, as follows: The declaration of a
- package-private type is like the declaration of a formal private
- type. The visible part of the package is like the generic formal
- part; these both specify a contract (that is, a set of operations and
- other things available for the private type). The private part of
- the package is like an instantiation of the generic; they both give a
- full_type_declaration that specifies implementation details of the
- private type. The clients of the package are like the body of the
- generic; usage of the private type in these places is restricted to
- the operations defined by the contract.
-
- 19.b In other words, being inside the package is like being outside the
- generic, and being outside the package is like being inside the
- generic; a generic is like an ``inside-out'' package.
-
- 19.c This analogy also works for private extensions in the same
- inside-out way.
-
- 19.d Many of the legality rules are defined with this analogy in mind.
- See, for example, the rules relating to operations of [formal]
- derived types.
-
- 19.e The completion rules for a private type are intentionally quite
- similar to the matching rules for a generic formal private type.
-
- 19.f This analogy breaks down in one respect: a generic actual subtype
- is a subtype, whereas the full view for a private type is always a
- new type. (We considered allowing the completion of a private_type_
- declaration to be a subtype_declaration, but the semantics just won't
- work.) This difference is behind the fact that a generic actual type
- can be class-wide, whereas the completion of a private type always
- declares a specific type.
-
- 20 (7) The ancestor type specified in a private_extension_declaration and
- the parent type specified in the corresponding declaration of a record
- extension given in the private part need not be the same -- the parent
- type of the full view can be any descendant of the ancestor type. In
- this case, for a primitive subprogram that is inherited from the
- ancestor type and not overridden, the formal parameter names and default
- expressions (if any) come from the corresponding primitive subprogram of
- the specified ancestor type, while the body comes from the corresponding
- primitive subprogram of the parent type of the full view. See 3.9.2.
-
-
- Examples
-
- 21 Examples of private type declarations:
-
- 22 type Key is private;
- type File_Name is limited private;
-
- 23 Example of a private extension declaration:
-
- 24 type List is new Ada.Finalization.Controlled with private;
-
-
- Extensions to Ada 83
-
- 24.a {extensions to Ada 83} The syntax for a private_type_
- declaration is augmented to allow the reserved word tagged.
-
- 24.b In Ada 83, a private type without discriminants cannot be
- completed with a type with discriminants. Ada 9X allows the full
- view to have discriminants, so long as they have defaults (that is,
- so long as the first subtype is definite). This change is made for
- uniformity with generics, and because the rule as stated is simpler
- and easier to remember than the Ada 83 rule. In the original version
- of Ada 83, the same restriction applied to generic formal private
- types. However, the restriction was removed by the ARG for generics.
- In order to maintain the ``generic contract/private type contract
- analogy'' discussed above, we have to apply the same rule to
- package-private types. Note that a private untagged type without
- discriminants can be completed with a tagged type with discriminants
- only if the full view is constrained, because discriminants of tagged
- types cannot have defaults.
-
- Wording Changes From Ada 83
-
- 24.c RM83-7.4.1(4), ``Within the specification of the package that
- declares a private type and before the end of the corresponding full
- type declaration, a restriction applies....'', is subsumed (and
- corrected) by the rule that a type shall be completely defined before
- it is frozen, and the rule that the parent type of a derived type
- declaration shall be completely defined, unless the derived type is a
- private extension.
- 7.3.1 Private Operations
-
- 1 [For a type declared in the visible part of a package or generic package,
- certain operations on the type do not become visible until later in the
- package -- either in the private part or the body. {private operations} Such
- private operations are available only inside the declarative region of the
- package or generic package.]
-
-
- Static Semantics
-
- 2 The predefined operators that exist for a given type are determined by
- the classes to which the type belongs. For example, an integer type has a
- predefined "+" operator. In most cases, the predefined operators of a type
- are declared immediately after the definition of the type; the exceptions are
- explained below. Inherited subprograms are also implicitly declared
- immediately after the definition of the type, except as stated below.
-
- 3 For a composite type, the characteristics (see 7.3) of the type are
- determined in part by the characteristics of its component types. At the
- place where the composite type is declared, the only characteristics of
- component types used are those characteristics visible at that place. If
- later within the immediate scope of the composite type additional
- characteristics become visible for a component type, then any corresponding
- characteristics become visible for the composite type. Any additional
- predefined operators are implicitly declared at that place.
-
- 4 The corresponding rule applies to a type defined by a derived_type_
- definition, if there is a place within its immediate scope where additional
- characteristics of its parent type become visible.
-
- 5 {become nonlimited} {nonlimited type (becoming nonlimited)} {limited type
- (becoming nonlimited)} [For example, an array type whose component type is
- limited private becomes nonlimited if the full view of the component type is
- nonlimited and visible at some later place within the immediate scope of the
- array type. In such a case, the predefined "=" operator is implicitly
- declared at that place, and assignment is allowed after that place.]
-
- 6 Inherited primitive subprograms follow a different rule. For a derived_
- type_definition, each inherited primitive subprogram is implicitly declared
- at the earliest place, if any, within the immediate scope of the type_
- declaration, but after the type_declaration, where the corresponding
- declaration from the parent is visible. If there is no such place, then the
- inherited subprogram is not declared at all. [An inherited subprogram that
- is not declared at all cannot be named in a call and cannot be overridden,
- but for a tagged type, it is possible to dispatch to it.] {94-4678.a}
- {94-4683.a}
-
- 7 For a private_extension_declaration, each inherited subprogram is
- declared immediately after the private_extension_declaration if the
- corresponding declaration from the ancestor is visible at that place.
- Otherwise, the inherited subprogram is not declared for the private
- extension, [though it might be for the full type].
-
- 7.a Reason: There is no need for the ``earliest place within the
- immediate scope'' business here, because a private_extension_
- declaration will be completed with a full_type_declaration, so we can
- hang the necessary private implicit declarations on the full_type_
- declaration.
-
- 7.b Discussion: The above rules matter only when the component
- type (or parent type) is declared in the visible part of a package,
- and the composite type (or derived type) is declared within the
- declarative region of that package (possibly in a nested package or a
- child package).
-
- 7.c Consider:
-
- 7.d package Parent is
- type Root is tagged null record;
- procedure Op1(X : Root);
-
- 7.e type My_Int is range 1..10;
- private
- procedure Op2(X : Root);
-
- 7.f type Another_Int is new My_Int;
- procedure Int_Op(X : My_Int);
- end Parent;
-
- 7.g with Parent; use Parent;
- package Unrelated is
- type T2 is new Root with null record;
- procedure Op2(X : T2);
- end Unrelated;
-
- 7.h package Parent.Child is
- type T3 is new Root with null record;
- -- Op1(T3) implicitly declared here.
-
- 7.i package Nested is
- type T4 is new Root with null record;
- private
- ...
- end Nested;
- private
- -- Op2(T3) implicitly declared here.
- ...
- end Parent.Child;
-
- 7.j with Unrelated; use Unrelated;
- package body Parent.Child is
- package body Nested is
- -- Op2(T4) implicitly declared here.
- end Nested;
-
- 7.k type T5 is new T2 with null record;
- end Parent.Child;
-
- 7.l Another_Int does not inherit Int_Op, because Int_Op does not
- ``exist'' at the place where Another_Int is declared.
-
- 7.m Type T2 inherits Op1 and Op2 from Root. However, the inherited
- Op2 is never declared, because Parent.Op2 is never visible within the
- immediate scope of T2. T2 explicitly declares its own Op2, but this
- is unrelated to the inherited one -- it does not override the
- inherited one, and occupies a different slot in the type descriptor.
-
- 7.n T3 inherits both Op1 and Op2. Op1 is implicitly declared
- immediately after the type declaration, whereas Op2 is declared at
- the beginning of the private part. Note that if Child were a private
- child of Parent, then Op1 and Op2 would both be implicitly declared
- immediately after the type declaration.
-
- 7.o T4 is similar to T3, except that the earliest place within T4's
- immediate scope where Root's Op2 is visible is in the body of Nested.
-
- 7.p If T3 or T4 were to declare a type-conformant Op2, this would
- override the one inherited from Root. This is different from the
- situation with T2.
-
- 7.q T5 inherits Op1 and two Op2's from T2. Op1 is implicitly
- declared immediately after the declaration of T5, as is the Op2 that
- came from Unrelated.Op2. However, the Op2 that originally came from
- Parent.Op2 is never implicitly declared for T5, since T2's version of
- that Op2 is never visible (anywhere -- it never got declared either).
- {94-4677.a} {94-4682.a} {94-4439.a}
-
- 7.r For all of these rules, implicit private parts and bodies are
- assumed as needed.
-
- 7.s It is possible for characteristics of a type to be revealed in
- more than one place:
-
- 7.t package P is
- type Comp1 is private;
- private
- type Comp1 is new Boolean;
- end P;
-
- 7.u package P.Q is
- package R is
- type Comp2 is limited private;
- type A is array(Integer range <>) of Comp2;
- private
- type Comp2 is new Comp1;
- -- A becomes nonlimited here.
- -- "="(A, A) return Boolean is implicitly declared here.
- ...
- end R;
- private
- -- Now we find out what Comp1 really is, which reveals
- -- more information about Comp2, but we're not within
- -- the immediate scope of Comp2, so we don't do anything
- -- about it yet.
- end P.Q;
-
- 7.v package body P.Q is
- package body R is
- -- Things like "xor"(A,A) return A are implicitly
- -- declared here.
- end R;
- end P.Q;
-
- {94-4444.a}
-
- 8 [The Class attribute is defined for tagged subtypes in 3.9. In
- addition,] for every subtype S of an untagged private type whose full view is
- tagged, the following attribute is defined:
-
- 9 S'Class
- Denotes the class-wide subtype corresponding to the full view
- of S. This attribute is allowed only from the beginning of
- the private part in which the full view is declared, until
- the declaration of the full view. [After the full view, the
- Class attribute of the full view can be used.]
-
-
- NOTES
- 10 (8) Because a partial view and a full view are two different views of
- one and the same type, outside of the defining package the
- characteristics of the type are those defined by the visible part.
- Within these outside program units the type is just a private type or
- private extension, and any language rule that applies only to another
- class of types does not apply. The fact that the full declaration might
- implement a private type with a type of a particular class (for example,
- as an array type) is relevant only within the declarative region of the
- package itself including any child units.
-
- 11 The consequences of this actual implementation are, however, valid
- everywhere. For example: any default initialization of components takes
- place; the attribute Size provides the size of the full view;
- finalization is still done for controlled components of the full view;
- task dependence rules still apply to components that are task objects.
-
- 12 (9) Partial views provide assignment (unless the view is limited),
- membership tests, selected components for the selection of discriminants
- and inherited components, qualification, and explicit conversion.
-
- 13 (10) For a subtype S of a partial view, S'Size is defined (see 13.3).
- For an object A of a partial view, the attributes A'Size and A'Address
- are defined (see 13.3). The Position, First_Bit, and Last_Bit
- attributes are also defined for discriminants and inherited components.
-
-
- Examples
-
- 14 Example of a type with private operations:
-
- 15 package Key_Manager is
- type Key is private;
- Null_Key : constant Key; -- a deferred constant declaration (see 7.4)
- procedure Get_Key(K : out Key);
- function "<" (X, Y : Key) return Boolean;
- private
- type Key is new Natural;
- Null_Key : constant Key := Key'First;
- end Key_Manager;
-
- 16 package body Key_Manager is
- Last_Key : Key := Null_Key;
- procedure Get_Key(K : out Key) is
- begin
- Last_Key := Last_Key + 1;
- K := Last_Key;
- end Get_Key;
-
- 17 function "<" (X, Y : Key) return Boolean is
- begin
- return Natural(X) < Natural(Y);
- end "<";
- end Key_Manager;
-
-
- NOTES
- 18 (11) Notes on the example: Outside of the package Key_Manager, the
- operations available for objects of type Key include assignment, the
- comparison for equality or inequality, the procedure Get_Key and the
- operator "<"; they do not include other relational operators such as
- ">=", or arithmetic operators.
-
- 19 The explicitly declared operator "<" hides the predefined operator
- "<" implicitly declared by the full_type_declaration. Within the body
- of the function, an explicit conversion of X and Y to the subtype
- Natural is necessary to invoke the "<" operator of the parent type.
- Alternatively, the result of the function could be written as not (X >=
- Y), since the operator ">=" is not redefined.
-
- 20 The value of the variable Last_Key, declared in the package body,
- remains unchanged between calls of the procedure Get_Key. (See also the
- NOTES of 7.2.)
-
-
- Wording Changes From Ada 83
-
- 20.a The phrase in RM83-7.4.2(7), ``...after the full type
- declaration'', doesn't work in the presence of child units, so we
- define that rule in terms of visibility.
-
- 20.b The definition of the Constrained attribute for private types
- has been moved to ``Obsolescent Features.'' (The Constrained
- attribute of an object has not been moved there.)
-
-
-
- 7.4 Deferred Constants
-
- 1 [Deferred constant declarations may be used to declare constants in the
- visible part of a package, but with the value of the constant given in the
- private part. They may also be used to declare constants imported from other
- languages (see Annex B).]
-
-
- Legality Rules
-
- 2 [{deferred constant declaration} A deferred constant declaration is an
- object_declaration with the reserved word constant but no initialization
- expression.]
-
- 2.a Proof: This is stated officially in Section 3.
-
- {deferred constant} The constant declared by a deferred constant declaration
- is called a deferred constant. {requires a completion [deferred constant
- declaration]} A deferred constant declaration requires a completion, which
- shall be a full constant declaration (called the full declaration of the
- deferred constant), or a pragma Import (see Annex B). {full declaration}
-
- 3 A deferred constant declaration that is completed by a full constant
- declaration shall occur immediately within the visible part of a package_
- specification. For this case, the following additional rules apply to the
- corresponding full declaration:
-
- 4 The full declaration shall occur immediately within the private
- part of the same package;
-
- 5 The deferred and full constants shall have the same type;
-
- 5.a Ramification: This implies that both the deferred declaration
- and the full declaration have to have a subtype_indication
- rather than an array_type_definition, because each array_type_
- definition would define a new type.
-
- 6 If the subtype defined by the subtype_indication in the deferred
- declaration is constrained, then the subtype defined by the
- subtype_indication in the full declaration shall match it
- statically. [On the other hand, if the subtype of the deferred
- constant is unconstrained, then the full declaration is still
- allowed to impose a constraint. The constant itself will be
- constrained, like all constants;]
-
- 7 If the deferred constant declaration includes the reserved word
- aliased, then the full declaration shall also.
-
- 7.a Ramification: On the other hand, the full constant can be
- aliased even if the deferred constant is not.
-
- 8 [A deferred constant declaration that is completed by a pragma Import
- need not appear in the visible part of a package_specification, and has no
- full constant declaration.]
-
- 9 The completion of a deferred constant declaration shall occur before the
- constant is frozen (see 7.4).
-
- 9.a Change: Rule moved here from 13.14, ``Freezing Rules'', as per
- WG9 resolution.
-
-
- Dynamic Semantics
-
- 10 {elaboration [deferred constant declaration]} The elaboration of a
- deferred constant declaration elaborates the subtype_indication or (only
- allowed in the case of an imported constant) the array_type_definition.
-
-
- NOTES
- 11 (12) The full constant declaration for a deferred constant that is of a
- given private type or private extension is not allowed before the
- corresponding full_type_declaration. This is a consequence of the
- freezing rules for types (see 13.14).
-
- 11.a Ramification: Multiple or single declarations are allowed for the
- deferred and the full declarations, provided that the equivalent
- single declarations would be allowed.
-
- 11.b Deferred constant declarations are useful for declaring constants
- of private views, and types with components of private views. They
- are also useful for declaring access-to-constant objects that
- designate variables declared in the private part of a package.
-
-
- Examples
-
- 12 Examples of deferred constant declarations:
-
- 13 Null_Key : constant Key; -- see 7.3.1
-
- 14 CPU_Identifier : constant String(1..8);
- pragma Import(Assembler, CPU_Identifier, Link_Name => "CPU_ID");
- -- see B.1
-
-
- Extensions to Ada 83
-
- 14.a {extensions to Ada 83} In Ada 83, a deferred constant is
- required to be of a private type declared in the same visible part.
- This restriction is removed for Ada 9X; deferred constants can be of
- any type.
-
- 14.b In Ada 83, a deferred constant declaration was not permitted
- to include a constraint, nor the reserved word aliased.
-
- 14.c In Ada 83, the rules required conformance of type marks; here
- we require static matching of subtypes if the deferred constant is
- constrained.
-
- 14.d A deferred constant declaration can be completed with a pragma
- Import. Such a deferred constant declaration need not be within a
- package_specification.
-
- 14.e The rules for too-early uses of deferred constants are
- modified in Ada 9X to allow more cases, and catch all errors at
- compile time. This change is necessary in order to allow deferred
- constants of a tagged type without violating the principle that for a
- dispatching call, there is always an implementation to dispatch to.
- It has the beneficial side-effect of catching some Ada-83-erroneous
- programs at compile time. The new rule fits in well with the new
- freezing-point rules. Furthermore, we are trying to convert
- undefined-value problems into bounded errors, and we were having
- trouble for the case of deferred constants. Furthermore,
- uninitialized deferred constants cause trouble for the shared
- variable / tasking rules, since they are really variable, even though
- they purport to be constant. In Ada 9X, they cannot be touched until
- they become constant.
-
- 14.f Note that we do not consider this change to be an upward
- incompatibility, because it merely changes an erroneous execution in
- Ada 83 into a compile-time error.
-
- 14.g The Ada 83 semantics are unclear in the case where the full
- view turns out to be an access type. It is a goal of the language
- design to prevent uninitialized access objects. One wonders if the
- implementation is required to initialize the deferred constant to
- null, and then initialize it (again!) to its real value. In Ada 9X,
- the problem goes away.
-
- Wording Changes From Ada 83
-
- 14.h Since deferred constants can now be of a nonprivate type, we
- have made this a stand-alone clause, rather than a subclause of 7.3,
- ``Private Types and Private Extensions''.
-
- 14.i Deferred constant declarations used to have their own syntax,
- but now they are simply a special case of object_declarations.
-
-
-
- 7.5 Limited Types
-
- 1 [{Limited type} [glossary entry]A limited type is (a view of) a type for
- which the assignment operation is not allowed. A nonlimited type is a (view
- of a) type for which the assignment operation is allowed.]
-
- 1.a Discussion: The concept of the value of a limited type is
- difficult to define, since the abstract value of a limited type often
- extends beyond its physical representation. In some sense, values of
- a limited type cannot be divorced from their object. The value is
- the object.
-
- 1.b In Ada 83, in the two places where limited types were defined
- by the language, namely tasks and files, an implicit level of
- indirection was implied by the semantics to avoid the separation of
- the value from an associated object. In Ada 9X, most limited types
- are passed by reference, and even return-ed by reference.
-
- 1.c To be honest: For a limited partial view whose full view is
- nonlimited, assignment is possible on parameter passing and function
- return. To prevent any copying whatsoever, one should make both the
- partial and full views limited.
-
-
- Legality Rules
-
- 2 If a tagged record type has any limited components, then the reserved
- word limited shall appear in its record_type_definition.
-
- 2.a Reason: This prevents tagged limited types from becoming
- nonlimited. Otherwise, the following could happen:
-
- 2.b package P is
- type T is limited private;
- type R is tagged
- record -- Illegal!
- -- This should say ``limited record''.
- X : T;
- end record;
- private
- type T is new Integer; -- R becomes nonlimited here.
- end P;
-
- 2.c package Q is
- type R2(Access_Discrim : access ...) is new R with
- record
- Y : Some_Task_Type;
- end record;
- end Q;
-
- 2.d If the above were legal, then assignment would be defined for
- R'Class in the body of P, which is bad news, given the access
- discriminant and the task.
-
-
- Static Semantics
-
- 3 {limited type} A type is limited if it is a descendant of one of the
- following:
-
- 4 a type with the reserved word limited in its definition;
-
- 4.a Ramification: Note that there is always a ``definition,''
- conceptually, even if there is no syntactic category called
- ``..._definition''.
-
- 5 a task or protected type;
-
- 6 a composite type with a limited component.
-
- 7 {nonlimited type} Otherwise, the type is nonlimited.
-
- 8 [There are no predefined equality operators for a limited type.]
-
-
- NOTES
- 9 (13) The following are consequences of the rules for limited types:
-
- 10 An initialization expression is not allowed in an object_
- declaration if the type of the object is limited.
-
- 11 A default expression is not allowed in a component_
- declaration if the type of the record component is limited.
-
- 12 An initialized allocator is not allowed if the designated
- type is limited.
-
- 13 A generic formal parameter of mode in must not be of a
- limited type.
-
- 14 (14) Aggregates are not available for a limited composite type.
- Concatenation is not available for a limited array type.
-
- 15 (15) The rules do not exclude a default_expression for a formal
- parameter of a limited type; they do not exclude a deferred constant of
- a limited type if the full declaration of the constant is of a
- nonlimited type.
-
- 16 (16) {become nonlimited} {nonlimited type (becoming nonlimited)}
- {limited type (becoming nonlimited)} As illustrated in 7.3.1, an
- untagged limited type can become nonlimited under certain circumstances.
-
- 16.a Ramification: Limited private types do not become nonlimited;
- instead, their full view can be nonlimited, which has a similar
- effect.
-
- 16.b It is important to remember that a single nonprivate type can be
- both limited and nonlimited in different parts of its scope. In
- other words, ``limited'' is a property that depends on where you are
- in the scope of the type. We don't call this a ``view property''
- because there is no particular declaration to declare the nonlimited
- view.
-
- 16.c Tagged types never become nonlimited.
-
-
- Examples
-
- 17 Example of a package with a limited type:
-
- 18 package IO_Package is
- type File_Name is limited private;
-
- 19 procedure Open (F : in out File_Name);
- procedure Close(F : in out File_Name);
- procedure Read (F : in File_Name; Item : out Integer);
- procedure Write(F : in File_Name; Item : in Integer);
- private
- type File_Name is
- limited record
- Internal_Name : Integer := 0;
- end record;
- end IO_Package;
-
- 20 package body IO_Package is
- Limit : constant := 200;
- type File_Descriptor is record ... end record;
- Directory : array (1 .. Limit) of File_Descriptor;
- ...
- procedure Open (F : in out File_Name) is ... end;
- procedure Close(F : in out File_Name) is ... end;
- procedure Read (F : in File_Name; Item : out Integer) is ... end;
- procedure Write(F : in File_Name; Item : in Integer) is ... end;
- begin
- ...
- end IO_Package;
-
-
- NOTES
- 21 (17) Notes on the example: In the example above, an outside subprogram
- making use of IO_Package may obtain a file name by calling Open and
- later use it in calls to Read and Write. Thus, outside the package, a
- file name obtained from Open acts as a kind of password; its internal
- properties (such as containing a numeric value) are not known and no
- other operations (such as addition or comparison of internal names) can
- be performed on a file name. Most importantly, clients of the package
- cannot make copies of objects of type File_Name.
-
- 22 This example is characteristic of any case where complete control
- over the operations of a type is desired. Such packages serve a dual
- purpose. They prevent a user from making use of the internal structure
- of the type. They also implement the notion of an encapsulated data
- type where the only operations on the type are those given in the
- package specification.
-
- 23 The fact that the full view of File_Name is explicitly declared
- limited means that parameter passing and function return will always be
- by reference (see 6.2 and 6.5).
- Extensions to Ada 83
-
- 23.a {extensions to Ada 83} The restrictions in RM83-7.4.4(4),
- which disallowed out parameters of limited types in certain cases,
- are removed.
-
- Wording Changes From Ada 83
-
- 23.b Since limitedness and privateness are orthogonal in Ada 9X
- (and to some extent in Ada 83), this is now its own clause rather
- than being a subclause of 7.3, ``Private Types and Private
- Extensions''.
-
-
-
- 7.6 User-Defined Assignment and Finalization
-
- 1 [{user-defined assignment} {assignment (user-defined)} Three kinds of
- actions are fundamental to the manipulation of objects: initialization,
- finalization, and assignment. Every object is initialized, either explicitly
- or by default, after being created (for example, by an object_declaration or
- allocator). Every object is finalized before being destroyed (for example,
- by leaving a subprogram_body containing an object_declaration, or by a call
- to an instance of Unchecked_Deallocation). An assignment operation is used
- as part of assignment_statements, explicit initialization, parameter passing,
- and other operations. {constructor: see initialization} {constructor: see
- Initialize} {destructor: see finalization}
-
- 2 Default definitions for these three fundamental operations are provided
- by the language, but {controlled type} a controlled type gives the user
- additional control over parts of these operations.
-
- 2.a Glossary entry: {Controlled type} A controlled type supports
- user-defined assignment and finalization. Objects are always
- finalized before being destroyed.
-
- {Initialize} {Finalize} {Adjust} In particular, the user can define, for a
- controlled type, an Initialize procedure which is invoked immediately after
- the normal default initialization of a controlled object, a Finalize
- procedure which is invoked immediately before finalization of any of the
- components of a controlled object, and an Adjust procedure which is invoked
- as the last step of an assignment to a (nonlimited) controlled object.]
-
- 2.b Ramification: Here's the basic idea of initialization, value
- adjustment, and finalization, whether or not user defined: When an
- object is created, if it is explicitly assigned an initial value, the
- assignment copies and adjusts the initial value. Otherwise,
- Initialize is applied to it (except in the case of an aggregate as a
- whole). An assignment_statement finalizes the target before copying
- in and adjusting the new value. Whenever an object goes away, it is
- finalized. Calls on Initialize and Adjust happen bottom-up; that is,
- components first, followed by the containing object. Calls on
- Finalize happens top-down; that is, first the containing object, and
- then its components. These ordering rules ensure that any components
- will be in a well-defined state when Initialize, Adjust, or Finalize
- is applied to the containing object.
-
-
- Static Semantics
-
- 3 The following language-defined library package exists:
-
- 4
- package Ada.Finalization is
- pragma Preelaborate(Finalization);{94-4528.a}
-
- 5 type Controlled is abstract tagged private;
-
- 6 procedure Initialize(Object : in out Controlled);
- procedure Adjust (Object : in out Controlled);
- procedure Finalize (Object : in out Controlled);
-
- 7 type Limited_Controlled is abstract tagged limited private;
-
- 8
- procedure Initialize(Object : in out Limited_Controlled);
- procedure Finalize (Object : in out Limited_Controlled);
- private
- ... -- not specified by the language
- end Ada.Finalization;
-
- 9 {controlled type} A controlled type is a descendant of Controlled or
- Limited_Controlled.
-
- 9.a Discussion: We say ``nonlimited controlled types'' when we
- want to talk about descendants of Controlled only.
-
- The (default) implementations of Initialize, Adjust, and Finalize have no
- effect. The predefined "=" operator of type Controlled always returns True,
- [since this operator is incorporated into the implementation of the
- predefined equality operator of types derived from Controlled, as explained
- in 4.5.2.] {94-4619.a} {94-4843.a} The type Limited_Controlled is like
- Controlled, except that it is limited and it lacks the primitive subprogram
- Adjust.
-
- 9.b Reason: We considered making Adjust and Finalize abstract.
- However, a reasonable coding convention is e.g. for Finalize to
- always call the parent's Finalize after doing whatever work is needed
- for the extension part. (Unlike CLOS, we have no way to do that
- automatically in Ada 9X.) For this to work, Finalize cannot be
- abstract. In a generic unit, for a generic formal abstract derived
- type whose ancestor is Controlled or Limited_Controlled, calling the
- ancestor's Finalize would be illegal if it were abstract, even though
- the actual type might have a concrete version.
-
- 9.c Types Controlled and Limited_Controlled are abstract, even
- though they have no abstract primitive subprograms. It is not clear
- that they need to be abstract, but there seems to be no harm in it,
- and it might make an implementation's life easier to know that there
- are no objects of these types -- in case the implementation wishes to
- make them ``magic'' in some way.
-
-
- Dynamic Semantics
-
- 10 {elaboration [object_declaration]} During the elaboration of an object_
- declaration, for every controlled subcomponent of the object that is not
- assigned an initial value (as defined in 3.3.1), Initialize is called on that
- subcomponent. Similarly, if the object as a whole is controlled and is not
- assigned an initial value, Initialize is called on the object. The same
- applies to the evaluation of an allocator, as explained in 4.8.
-
- 11 For an extension_aggregate whose ancestor_part is a subtype_mark,
- Initialize is called on all controlled subcomponents of the ancestor part; if
- the type of the ancestor part is itself controlled, the Initialize procedure
- of the ancestor type is called, unless that Initialize procedure is abstract.
-
- 11.a Discussion: Example:
-
- 11.b type T1 is new Controlled with
- record
- ... -- some components might have defaults
- end record;
-
- 11.c type T2 is new Controlled with
- record
- X : T1; -- no default
- Y : T1 := ...; -- default
- end record;
-
- 11.d A : T2;
- B : T2 := ...;
-
- 11.e As part of the elaboration of A's declaration, A.Y is assigned
- a value; therefore Initialize is not applied to A.Y. Instead, Adjust
- is applied to A.Y as part of the assignment operation. Initialize is
- applied to A.X and to A, since those objects are not assigned an
- initial value. The assignment to A.Y is not considered an assignment
- to A.
-
- 11.f For the elaboration of B's declaration, Initialize is not
- called at all. Instead the assignment adjusts B's value; that is, it
- applies Adjust to B.X, B.Y, and B.
-
- 12 Initialize and other initialization operations are done in an arbitrary
- order, except as follows. Initialize is applied to an object after
- initialization of its subcomponents, if any [(including both implicit
- initialization and Initialize calls)]. If an object has a component with an
- access discriminant constrained by a per-object expression, Initialize is
- applied to this component after any components that do not have such
- discriminants. For an object with several components with such a
- discriminant, Initialize is applied to them in order of their component_
- declarations. For an allocator, any task activations follow all calls on
- Initialize.
-
- 12.a Reason: The fact that Initialize is done for subcomponents
- first allows Initialize for a composite object to refer to its
- subcomponents knowing they have been properly initialized.
-
- 12.b The fact that Initialize is done for components with access
- discriminants after other components allows the Initialize operation
- for a component with a self-referential access discriminant to assume
- that other components of the enclosing object have already been
- properly initialized. For multiple such components, it allows some
- predictability.
-
- 13 {assignment operation} When a target object with any controlled parts is
- assigned a value, [either when created or in a subsequent assignment_
- statement,] the assignment operation proceeds as follows:
-
- 14 The value of the target becomes the assigned value.
-
- 15 {adjusting the value of an object} {adjustment} The value of the
- target is adjusted.
-
- 15.a Ramification: If any parts of the object are controlled,
- abort is deferred during the assignment operation.
-
- 16 {adjusting the value of an object} {adjustment} To adjust the value of a
- [(nonlimited)] composite object, the values of the components of the object
- are first adjusted in an arbitrary order, and then, if the object is
- controlled, Adjust is called. Adjusting the value of an elementary object
- has no effect[, nor does adjusting the value of a composite object with no
- controlled parts.]
-
- 16.a Ramification: Adjustment is never performed for values of a
- by-reference limited type, since these types do not support copying.
-
- 16.b Reason: The verbiage in the Initialize rule about access
- discriminants constrained by per-object expressions is not necessary
- here, since such types are limited, and therefore are never adjusted.
-
- 17 {execution [assignment_statement]} For an assignment_statement, [ after
- the name and expression have been evaluated, and any conversion (including
- constraint checking) has been done,] an anonymous object is created, and the
- value is assigned into it; [that is, the assignment operation is applied].
- [(Assignment includes value adjustment.)] The target of the assignment_
- statement is then finalized. The value of the anonymous object is then
- assigned into the target of the assignment_statement. Finally, the anonymous
- object is finalized. [As explained below, the implementation may eliminate
- the intermediate anonymous object, so this description subsumes the one given
- in 5.2, ``Assignment Statements''.]
-
- 17.a Reason: An alternative design for user-defined assignment
- might involve an Assign operation instead of Adjust:
-
- 17.b procedure Assign(Target : in out Controlled; Source : in out Contro\
- lled);
-
- 17.c Or perhaps even a syntax like this:
-
- 17.d procedure ":="(Target : in out Controlled; Source : in out Controll\
- ed);
-
- 17.e Assign (or ":=") would have the responsibility of doing the
- copy, as well as whatever else is necessary. This would have the
- advantage that the Assign operation knows about both the target and
- the source at the same time -- it would be possible to do things like
- reuse storage belonging to the target, for example, which Adjust
- cannot do. However, this sort of design would not work in the case
- of unconstrained discriminated variables, because there is no way to
- change the discriminants individually. For example:
-
- 17.f type Mutable(D : Integer := 0) is
- record
- X : Array_Of_Controlled_Things(1..D);
- case D is
- when 17 => Y : Controlled_Thing;
- when others => null;
- end D;
- end record;
-
- 17.g An assignment to an unconstrained variable of type Mutable can
- cause some of the components of X, and the component Y, to appear
- and/or disappear. There is no way to write the Assign operation to
- handle this sort of case.
-
- 17.h Forbidding such cases is not an option -- it would cause
- generic contract model violations.
-
-
- Implementation Permissions
-
- 18 An implementation is allowed to relax the above rules [(for nonlimited
- controlled types)] in the following ways:
-
- 18.a Proof: The phrase ``for nonlimited controlled types'' follows
- from the fact that all of the following permissions apply to cases
- involving assignment. It is important because the programmer can
- count on a stricter semantics for limited controlled types.
-
- 19 For an assignment_statement that assigns to an object the value
- of that same object, the implementation need not do anything.
- {94-4495.a}
-
- 19.a Ramification: In other words, even if an object is controlled
- and a combination of Finalize and Adjust on the object might
- have a net side effect, they need not be performed.
-
- 20 For an assignment_statement for a noncontrolled type, the
- implementation may finalize and assign each component of the
- variable separately (rather than finalizing the entire variable
- and assigning the entire new value) unless a discriminant of the
- variable is changed by the assignment.
-
- 20.a Reason: For example, in a slice assignment, an anonymous object
- is not necessary if the slice is copied component-by-component
- in the right direction, since array types are not controlled
- (although their components may be). Note that the direction,
- and even the fact that it's a slice assignment, can in general
- be determined only at run time.
-
- 21 For an aggregate or function call whose value is assigned into a
- target object, the implementation need not create a separate
- anonymous object if it can safely create the value of the
- aggregate or function call directly in the target object.
- Similarly, for an assignment_statement, the implementation need
- not create an anonymous object if the value being assigned is the
- result of evaluating a name denoting an object (the source
- object) whose storage cannot overlap with the target. If the
- source object might overlap with the target object, then the
- implementation can avoid the need for an intermediary anonymous
- object by exercising one of the above permissions and perform the
- assignment one component at a time (for an overlapping array
- assignment), or not at all (for an assignment where the target
- and the source of the assignment are the same object). Even if
- an anonymous object is created, the implementation may move its
- value to the target object as part of the assignment without
- re-adjusting so long as the anonymous object has no aliased
- subcomponents.
-
- 21.a Ramification: In the aggregate case, only one value adjustment
- is necessary, and there is no anonymous object to be finalized.
-
- 21.b In the assignment_statement case as well, no finalization of the
- anonymous object is needed. On the other hand, if the target
- has aliased subcomponents, then an adjustment takes place
- directly on the target object as the last step of the
- assignment, since some of the subcomponents may be
- self-referential or otherwise position-dependent.
-
-
- Extensions to Ada 83
-
- 21.c {extensions to Ada 83} Controlled types and user-defined
- finalization are new to Ada 9X. (Ada 83 had finalization semantics
- only for masters of tasks.)
-
-
-
- 7.6.1 Completion and Finalization
-
- 1 [This subclause defines completion and leaving of the execution of
- constructs and entities. A master is the execution of a construct that
- includes finalization of local objects after it is complete (and after
- waiting for any local tasks -- see 9.3), but before leaving. {94-4715.a}
- Other constructs and entities are left immediately upon completion.
- {cleanup: see finalization} {destructor: see finalization}]
-
-
- Dynamic Semantics
-
- 2 {completion and leaving (completed and left)} {completion (run-time
- concept)} The execution of a construct or entity is complete when the end of
- that execution has been reached, or when a transfer of control (see 5.1)
- causes it to be abandoned. {normal completion} {completion (normal)}
- {abnormal completion} {completion (abnormal)} Completion due to reaching the
- end of execution, or due to the transfer of control of an exit_, return_,
- goto_, or requeue_statement or of the selection of a terminate_alternative is
- normal completion. Completion is abnormal otherwise [-- when control is
- transferred out of a construct due to abort or the raising of an exception].
-
- 2.a Discussion: Don't confuse the run-time concept of completion
- with the compile-time concept of completion defined in 3.11.1.
-
- 3 {leaving} {left} After execution of a construct or entity is complete, it
- is left, meaning that execution continues with the next action, as defined
- for the execution that is taking place. {master} Leaving an execution
- happens immediately after its completion, except in the case of a master:
- the execution of a task_body, a block_statement, a subprogram_body, an entry_
- body, or an accept_statement. A master is finalized after it is complete,
- and before it is left. {94-4715.a}
-
- 3.a Reason: Note that although an accept_statement has no
- declarative_part, it can call functions and evaluate aggregates,
- possibly causing anonymous controlled objects to be created, and we
- don't want those objects to escape outside the rendezvous.
-
- 4 {finalization (of a master)} For the finalization of a master, dependent
- tasks are first awaited, as explained in 9.3. Then each object whose
- accessibility level is the same as that of the master is finalized if the
- object was successfully initialized and still exists. {94-4715.a} [These
- actions are performed whether the master is left by reaching the last
- statement or via a transfer of control.]
-
- 4.a Ramification: As explained in 3.10.2, the set of objects with
- the same accessibility level as that of the master includes objects
- declared immediately within the master, objects declared in nested
- packages, objects created by allocators (if the ultimate ancestor
- access type is declared in one of those places) and subcomponents of
- all of these things. If an object was already finalized by
- Unchecked_Deallocation, then it is not finalized again when the
- master is left.
-
- 4.b Note that any object whose accessibility level is deeper than
- that of the master would no longer exist; those objects would have
- been finalized by some inner master. Thus, after leaving a master,
- the only objects yet to be finalized are those whose accessibility
- level is less deep than that of the master. {94-4715.a}
-
- 4.c To be honest: Subcomponents of objects due to be finalized are
- not finalized by the finalization of the master; they are finalized
- by the finalization of the containing object.
-
- 4.d Reason: We need to finalize subcomponents of objects even if
- the containing object is not going to get finalized because it was
- not fully initialized. But if the containing object is finalized, we
- don't want to require repeated finalization of the subcomponents, as
- might normally be implied by the recursion in finalization of a
- master and the recursion in finalization of an object.
-
- When a transfer of control causes completion of an execution, each included
- master is finalized in order, from innermost outward.
-
- 4.e To be honest: Formally, completion and leaving refer to
- executions of constructs or entities. However, the standard
- sometimes (informally) refers to the constructs or entities whose
- executions are being completed. Thus, for example, ``the subprogram_
- call or task is complete'' really means ``the execution of the
- subprogram_call or task is complete.''
-
- 5 {finalization (of an object) [distributed]} For the finalization of an
- object:
-
- 6 If the object is of an elementary type, finalization has no
- effect;
-
- 7 If the object is of a controlled type, the Finalize procedure is
- called;
-
- 8 If the object is of a protected type, the actions defined in 9.4
- are performed;
-
- 9 If the object is of a composite type, then after performing the
- above actions, if any, every component of the object is finalized
- in an arbitrary order, except as follows: if the object has a
- component with an access discriminant constrained by a per-object
- expression, this component is finalized before any components
- that do not have such discriminants; for an object with several
- components with such a discriminant, they are finalized in the
- reverse of the order of their component_declarations.
-
- 9.a Reason: This allows the finalization of a component with an
- access discriminant to refer to other components of the
- enclosing object prior to their being finalized.
-
- 10 {execution [instance of Unchecked_Deallocation]} Immediately before an
- instance of Unchecked_Deallocation reclaims the storage of an object, the
- object is finalized. [If an instance of Unchecked_Deallocation is never
- applied to an object created by an allocator, the object will still exist
- when the corresponding master completes, and it will be finalized then.]
-
- 11 The order in which the finalization of a master performs finalization of
- objects is as follows: Objects created by declarations in the master are
- finalized in the reverse order of their creation. For objects that were
- created by allocators for an access type whose ultimate ancestor is declared
- in the master, this rule is applied as though each such object that still
- exists had been created in an arbitrary order at the first freezing point
- (see 13.14) of the ultimate ancestor type.
-
- 11.a Reason: Note that we talk about the type of the allocator
- here. There may be access values of a (general) access type pointing
- at objects created by allocators for some other type; these are not
- finalized at this point.
-
- 11.b The freezing point of the ultimate ancestor access type is
- chosen because before that point, pool elements cannot be created,
- and after that point, access values designating (parts of) the pool
- elements can be created. This is also the point after which the pool
- object cannot have been declared. We don't want to finalize the pool
- elements until after anything finalizing objects that contain access
- values designating them. Nor do we want to finalize pool elements
- after finalizing the pool object itself.
-
- 11.c Ramification: Finalization of allocated objects is done
- according to the (ultimate ancestor) allocator type, not according to
- the storage pool in which they are allocated. Pool finalization
- might reclaim storage (see 13.11, ``Storage Management''), but has
- nothing (directly) to do with finalization of the pool elements.
-
- 11.d Note that finalization is done only for objects that still
- exist; if an instance of Unchecked_Deallocation has already gotten
- rid of a given pool element, that pool element will not be finalized
- when the master is left.
-
- 11.e Note that a deferred constant declaration does not create the
- constant; the full constant declaration creates it. Therefore, the
- order of finalization depends on where the full constant declaration
- occurs, not the deferred constant declaration.
-
- 11.f An imported object is not created by its declaration. It is
- neither initialized nor finalized.
-
- 11.g Implementation Note: An implementation has to ensure that the
- storage for an object is not reclaimed when references to the object
- are still possible (unless, of course, the user explicitly requests
- reclamation via an instance of Unchecked_Deallocation). This
- implies, in general, that objects cannot be deallocated one by one as
- they are finalized; a subsequent finalization might reference an
- object that has been finalized, and that object had better be in its
- (well-defined) finalized state.
-
- 12 {execution [assignment_statement]} The target of an assignment statement
- is finalized before copying in the new value, as explained in 7.6.
-
- 13 The anonymous objects created by function calls and by aggregates are
- finalized no later than the end of the innermost enclosing declarative_item
- or statement; if that is a compound_statement, they are finalized before
- starting the execution of any statement within the compound_statement.
-
- 13.a To be honest: This is not to be construed as permission to
- call Finalize asynchronously with respect to normal user code. For
- example,
-
- 13.b declare
- X : Some_Controlled_Type := F(G(...));
- -- The anonymous objects created for F and G are finalized
- -- no later than this point.
- Y : ...
- begin
- ...
- end;
-
- 13.c The anonymous object for G should not be finalized at some
- random point in the middle of the body of F, because F might
- manipulate the same data structures as the Finalize operation,
- resulting in erroneous access to shared variables.
-
- 13.d Reason: It might be quite inconvenient for the implementation
- to defer finalization of the anonymous object for G until after
- copying the value of F into X, especially if the size of the result
- is not known at the call site.
-
-
- Bounded (Run-Time) Errors
-
- 14 {bounded error} It is a bounded error for a call on Finalize or Adjust
- to propagate an exception. The possible consequences depend on what action
- invoked the Finalize or Adjust operation:
-
- 14.a Ramification: It is not a bounded error for Initialize to
- propagate an exception. If Initialize propagates an exception, then
- no further calls on Initialize are performed, and those components
- that have already been initialized (either explicitly or by default)
- are finalized in the usual way.
-
- 15 {Program_Error (raised by failure of run-time check)} For a
- Finalize invoked as part of an assignment_statement, Program_
- Error is raised at that point.
-
- 16 {Program_Error (raised by failure of run-time check)} For an
- Adjust invoked as part of an assignment operation, any other
- adjustments due to be performed are performed, and then Program_
- Error is raised.
-
- 17 {Program_Error (raised by failure of run-time check)} For a
- Finalize invoked as part of a call on an instance of Unchecked_
- Deallocation, any other finalizations due to be performed are
- performed, and then Program_Error is raised.
-
- 18 {Program_Error (raised by failure of run-time check)} For a
- Finalize invoked by the transfer of control of an exit_, return_,
- goto_, or requeue_statement, Program_Error is raised no earlier
- than after the finalization of the master being finalized when
- the exception occurred, and no later than the point where normal
- execution would have continued. Any other finalizations due to
- be performed up to that point are performed before raising
- Program_Error.
-
- 18.a Ramification: For example, upon leaving a block_statement due
- to a goto_statement, the Program_Error would be raised at the
- point of the target statement denoted by the label, or else in
- some more dynamically nested place, but not so nested as to
- allow an exception_handler that has visibility upon the
- finalized object to handle it. For example,
-
- 18.b procedure Main is
- begin
- <<The_Label>>
- Outer_Block_Statement : declare
- X : Some_Controlled_Type;
- begin
- Inner_Block_Statement : declare
- Y : Some_Controlled_Type;
- Z : Some_Controlled_Type;
- begin
- goto The_Label;
- exception
- when Program_Error => ... -- Handler number 1.
- end;
- exception
- when Program_Error => ... -- Handler number 2.
- end;
- exception
- when Program_Error => ... -- Handler number 3.
- end Main;
-
- 18.c The goto_statement will first cause Finalize(Y) to be called.
- Suppose that Finalize(Y) propagates an exception. Program_Error
- will be raised after leaving Inner_Block_Statement, but before
- leaving Main. Thus, handler number 1 cannot handle this
- Program_Error; it will be handled either by handler number 2 or
- handler number 3. If it is handled by handler number 2, then
- Finalize(Z) will be done before executing the handler. If it is
- handled by handler number 3, then Finalize(Z) and Finalize(X)
- will both be done before executing the handler.
-
- 19 For a Finalize invoked by a transfer of control that is due to
- raising an exception, any other finalizations due to be performed
- for the same master are performed; Program_Error is raised
- immediately after leaving the master.
-
- 19.a Ramification: If, in the above example, the goto_statement were
- replaced by a raise_statement, then the Program_Error would be
- handled by handler number 2, and Finalize(Z) would be done
- before executing the handler.
-
- 19.b Reason: We considered treating this case in the same way as the
- others, but that would render certain exception_handlers
- useless. For example, suppose the only exception_handler is one
- for others in the main subprogram. If some deeply nested call
- raises an exception, causing some Finalize operation to be
- called, which then raises an exception, then normal execution
- ``would have continued'' at the beginning of the exception_
- handler. Raising Program_Error at that point would cause that
- handler's code to be skipped. One would need two nested
- exception_handlers to be sure of catching such cases!
-
- 19.c On the other hand, the exception_handler for a given master
- should not be allowed to handle exceptions raised during
- finalization of that master.
-
- 20 For a Finalize invoked by a transfer of control due to an abort
- or selection of a terminate alternative, the exception is
- ignored; any other finalizations due to be performed are
- performed.
-
- 20.a Ramification: This case includes an asynchronous transfer of
- control.
-
- 20.b To be honest: {Program_Error (raised by failure of run-time
- check)} This violates the general principle that it is always
- possible for a bounded error to raise Program_Error (see 1.1.5,
- ``Classification of Errors'').
-
-
- NOTES
- 21 (18) The rules of Section 10 imply that immediately prior to partition
- termination, Finalize operations are applied to library-level controlled
- objects (including those created by allocators of library-level access
- types, except those already finalized). This occurs after waiting for
- library-level tasks to terminate.
-
- 21.a Discussion: We considered defining a pragma that would apply to a
- controlled type that would suppress Finalize operations for
- library-level objects of the type upon partition termination. This
- would be useful for types whose finalization actions consist of
- simply reclaiming global heap storage, when this is already provided
- automatically by the environment upon program termination.
-
- 22 (19) A constant is only constant between its initialization and
- finalization. Both initialization and finalization are allowed to
- change the value of a constant.
-
- 23 (20) Abort is deferred during certain operations related to controlled
- types, as explained in 9.8. Those rules prevent an abort from causing a
- controlled object to be left in an ill-defined state.
-
- 24 (21) The Finalize procedure is called upon finalization of a controlled
- object, even if Finalize was called earlier, either explicitly or as
- part of an assignment; hence, if a controlled type is visibly controlled
- (implying that its Finalize primitive is directly callable), or is
- nonlimited (implying that assignment is allowed), its Finalize procedure
- should be designed to have no ill effect if it is applied a second time
- to the same object.
-
- 24.a Discussion: Or equivalently, a Finalize procedure should be
- ``idempotent''; applying it twice to the same object should be
- equivalent to applying it once.
-
- 24.b Reason: A user-written Finalize procedure should be idempotent
- since it can be called explicitly by a client (at least if the type
- is "visibly" controlled). Also, Finalize is used implicitly as part
- of the assignment_statement if the type is nonlimited, and an abort
- is permitted to disrupt an assignment_statement between finalizing
- the left-hand side and assigning the new value to it (an abort is not
- permitted to disrupt an assignment operation between copying in the
- new value and adjusting it).
-
- 24.c Discussion: Either Initialize or Adjust, but not both, is applied
- to (almost) every controlled object when it is created: Initialize
- is done when no initial value is assigned to the object, whereas
- Adjust is done as part of assigning the initial value. The one
- exception is the anonymous object created by an aggregate; Initialize
- is not applied to the aggregate as a whole, nor is the value of the
- aggregate adjusted.
-
- 24.d {assignment operation (list of uses)} All of the following use the
- assignment operation, and thus perform value adjustment:
-
- 24.e the assignment_statement (see 5.2);
-
- 24.f explicit initialization of a stand-alone object (see
- 3.3.1) or of a pool element (see 4.8);
-
- 24.g default initialization of a component of a stand-alone
- object or pool element (in this case, the value of each
- component is assigned, and therefore adjusted, but the
- value of the object as a whole is not adjusted);
-
- 24.h function return, when the result type is not a
- return-by-reference type (see 6.5); (adjustment of the
- result happens before finalization of the function;
- values of return-by-reference types are not adjusted);
-
- 24.i predefined operators (although the only one that matters
- is concatenation; see 4.5.3);
-
- 24.j generic formal objects of mode in (see 12.4); these are
- defined in terms of constant_declarations; and
-
- 24.k aggregates (see 4.3) (in this case, the value of each
- component, and the parent part, for an extension_
- aggregate, is assigned, and therefore adjusted, but the
- value of the aggregate as a whole is not adjusted;
- neither is Initialize called);
-
- 24.l The following also use the assignment operation, but adjustment
- never does anything interesting in these cases:
-
- 24.m By-copy parameter passing uses the assignment operation
- (see 6.4.1), but controlled objects are always passed by
- reference, so the assignment operation never does
- anything interesting in this case. If we were to allow
- by-copy parameter passing for controlled objects, we
- would need to make sure that the actual is finalized
- before doing the copy back for [in] out parameters. The
- finalization of the parameter itself needs to happen
- after the copy back (if any), similar to the finalization
- of an anonymous function return object or aggregate
- object.
-
- 24.n For loops use the assignment operation (see 5.5), but
- since the type of the loop parameter is never controlled,
- nothing interesting happens there, either.
-
- 24.o Because Controlled and Limited_Controlled are library-level tagged
- types, all controlled types will be library-level types, because of
- the accessibility rules (see 3.10.2 and 3.9.1). This ensures that
- the Finalize operations may be applied without providing any
- ``display'' or ``static-link.'' This simplifies finalization as a
- result of garbage collection, abort, and asynchronous transfer of
- control.
-
- 24.p Finalization of the parts of a protected object are not done as
- protected actions. It is possible (in pathological cases) to create
- tasks during finalization that access these parts in parallel with
- the finalization itself. This is an erroneous use of shared
- variables.
-
- 24.q Implementation Note: One implementation technique for finalization
- is to chain the controlled objects together on a per-task list. When
- leaving a master, the list can be walked up to a marked place. The
- links needed to implement the list can be declared (privately) in
- types Controlled and Limited_Controlled, so they will be inherited by
- all controlled types.
-
- 24.r Another implementation technique, which we refer to as the
- ``PC-map'' approach essentially implies inserting exception handlers
- at various places, and finalizing objects based on where the
- exception was raised.
-
- 24.s {PC-map approach to finalization} {program-counter-map approach to
- finalization} The PC-map approach is for the compiler/linker to
- create a map of code addresses; when an exception is raised, or abort
- occurs, the map can be consulted to see where the task was executing,
- and what finalization needs to be performed. This approach was given
- in the Ada 83 Rationale as a possible implementation strategy for
- exception handling -- the map is consulted to determine which
- exception handler applies.
-
- 24.t If the PC-map approach is used, the implementation must take care
- in the case of arrays. The generated code will generally contain a
- loop to initialize an array. If an exception is raised part way
- through the array, the components that have been initialized must be
- finalized, and the others must not be finalized.
-
- 24.u It is our intention that both of these implementation methods
- should be possible.
-
-
- Wording Changes From Ada 83
-
- 24.v Finalization depends on the concepts of completion and
- leaving, and on the concept of a master. Therefore, we have moved
- the definitions of these concepts here, from where they used to be in
- Section 9. These concepts also needed to be generalized somewhat.
- Task waiting is closely related to user-defined finalization; the
- rules here refer to the task-waiting rules of Section 9.
-
-
-
- Section 8: Visibility Rules
-
-
- 1 [The rules defining the scope of declarations and the rules defining
- which identifiers, character_literals, and operator_symbols are visible at
- (or from) various places in the text of the program are described in this
- section. The formulation of these rules uses the notion of a declarative
- region.
-
- 2 As explained in Section 3, a declaration declares a view of an entity and
- associates a defining name with that view. The view comprises an
- identification of the viewed entity, and possibly additional properties. A
- usage name denotes a declaration. It also denotes the view declared by that
- declaration, and denotes the entity of that view. Thus, two different usage
- names might denote two different views of the same entity; in this case they
- denote the same entity.]
- 2.a To be honest: In some cases, a usage name that denotes a
- declaration does not denote the view declared by that declaration,
- nor the entity of that view, but instead denotes a view of the
- current instance of the entity, and denotes the current instance of
- the entity. This sometimes happens when the usage name occurs inside
- the declarative region of the declaration.
-
-
- Wording Changes From Ada 83
-
- 2.b We no longer define the term ``basic operation;'' thus we no
- longer have to worry about the visibility of them. Since they were
- essentially always visible in Ada 83, this change has no effect. The
- reason for this change is that the definition in Ada 83 was
- confusing, and not quite correct, and we found it difficult to fix.
- For example, one wonders why an if_statement was not a basic
- operation of type Boolean. For another example, one wonders what it
- meant for a basic operation to be ``inherent in'' something.
- Finally, this fixes the problem addressed by AI-00027/07.
-
-
-
- 8.1 Declarative Region
-
- Static Semantics
-
- 1 {declarative region (of a construct)} For each of the following
- constructs, there is a portion of the program text called its declarative
- region, [within which nested declarations can occur]:
-
- 2 any declaration, other than that of an enumeration type, that is
- not a completion [of a previous declaration];
-
- 3 a block_statement;
-
- 4 a loop_statement;
-
- 5 an accept_statement;
-
- 6 an exception_handler.
-
- 7 The declarative region includes the text of the construct together with
- additional text determined [(recursively)], as follows:
-
- 8 If a declaration is included, so is its completion, if any.
-
- 9 If the declaration of a library unit [(including Standard -- see
- 10.1.1)] is included, so are the declarations of any child units
- [(and their completions, by the previous rule)]. The child
- declarations occur after the declaration.
-
- 10 If a body_stub is included, so is the corresponding subunit.
-
- 11 If a type_declaration is included, then so is a corresponding
- record_representation_clause, if any.
-
- 11.a Reason: This is so that the component_declarations can be
- directly visible in the record_representation_clause.
-
- 12 The declarative region of a declaration is also called the declarative
- region of any view or entity declared by the declaration.
-
- 12.a Reason: The constructs that have declarative regions are the
- constructs that can have declarations nested inside them. Nested
- declarations are declared in that declarative region. The one
- exception is for enumeration literals; although they are nested
- inside an enumeration type declaration, they behave as if they were
- declared at the same level as the type.
-
- 12.b To be honest: A declarative region does not include parent_
- unit_names.
-
- 12.c Ramification: A declarative region does not include context_
- clauses.
-
- 13 {occur immediately within} {immediately within} {within (immediately)}
- {immediately enclosing} {enclosing (immediately)} A declaration occurs
- immediately within a declarative region if this region is the innermost
- declarative region that encloses the declaration (the immediately enclosing
- declarative region), not counting the declarative region (if any) associated
- with the declaration itself.
-
- 13.a Discussion: Don't confuse the declarative region of a
- declaration with the declarative region in which it immediately
- occurs.
-
- 14 [{local to} A declaration is local to a declarative region if the
- declaration occurs immediately within the declarative region.]
-
- 14.a Ramification: That is, "occurs immediately within" and "local
- to" are synonyms (when referring to declarations).
-
- [An entity is local to a declarative region if the entity is declared by a
- declaration that is local to the declarative region.]
-
- 14.b Ramification: Thus, ``local to'' applies to both declarations
- and entities, whereas ``occurs immediately within'' only applies to
- declarations. We use this term only informally; for cases where
- precision is required, we use the term "occurs immediately within",
- since it is less likely to cause confusion.
-
- 15 {global to} A declaration is global to a declarative region if the
- declaration occurs immediately within another declarative region that
- encloses the declarative region. An entity is global to a declarative region
- if the entity is declared by a declaration that is global to the declarative
- region.
-
-
- NOTES
- 16 (1) The children of a parent library unit are inside the parent's
- declarative region, even though they do not occur inside the parent's
- declaration or body. This implies that one can use (for example) "P.Q"
- to refer to a child of P whose defining name is Q, and that after "use
- P;" Q can refer (directly) to that child.
-
- 17 (2) As explained above and in 10.1.1, ``Compilation Units - Library
- Units'', all library units are descendants of Standard, and so are
- contained in the declarative region of Standard. They are not inside
- the declaration or body of Standard, but they are inside its declarative
- region.
-
- 18 (3) For a declarative region that comes in multiple parts, the text of
- the declarative region does not contain any text that might appear
- between the parts. Thus, when a portion of a declarative region is said
- to extend from one place to another in the declarative region, the
- portion does not contain any text that might appear between the parts of
- the declarative region.
-
- 18.a Discussion: It is necessary for the things that have a declarative
- region to include anything that contains declarations (except for
- enumeration type declarations). This includes any declaration that
- has a profile (that is, subprogram_declaration, subprogram_body,
- entry_declaration, subprogram_renaming_declaration, formal_
- subprogram_declaration, access-to-subprogram type_declaration), any-
- thing that has a discriminant_part (that is, various kinds of type_
- declaration), anything that has a component_list (that is, record
- type_declaration and record extension type_declaration), and finally
- the declarations of task and protected units and packages.
-
-
- Wording Changes From Ada 83
-
- 18.b It was necessary to extend Ada 83's definition of declarative
- region to take the following Ada 9X features into account:
-
- 18.c Child library units.
-
- 18.d Derived types/type extensions -- we need a declarative
- region for inherited components and also for new
- components.
-
- 18.e All the kinds of types that allow discriminants.
-
- 18.f Protected units.
-
- 18.g Entries that have bodies instead of accept statements.
-
- 18.h The choice_parameter_specification of an exception_
- handler.
-
- 18.i The formal parameters of access-to-subprogram types.
-
- 18.j Renamings-as-body.
-
- 18.k Discriminated and access-to-subprogram type declarations need
- a declarative region. Enumeration type declarations cannot have one,
- because you don't have to say "Color.Red" to refer to the literal Red
- of Color. For other type declarations, it doesn't really matter
- whether or not there is an associated declarative region, so for
- simplicity, we give one to all types except enumeration types.
-
- 18.l We now say that an accept_statement has its own declarative
- region, rather than being part of the declarative region of the
- entry_declaration, so that declarative regions are properly nested
- regions of text, so that it makes sense to talk about "inner
- declarative regions," and "...extends to the end of a declarative
- region." Inside an accept_statement, the name of one of the
- parameters denotes the parameter_specification of the accept_
- statement, not that of the entry_declaration. If the accept_
- statement is nested within a block_statement, these parameter_
- specifications can hide declarations of the block_statement. The
- semantics of such cases was unclear in RM83.
-
- 18.m To be honest: Unfortunately, we have the same problem for the
- entry name itself -- it should denote the accept_statement, but
- accept_statements are not declarations. They should be, and they
- should hide the entry from all visibility within themselves.
-
- 18.n Note that we can't generalize this to entry_bodies, or other
- bodies, because the declarative_part of a body is not supposed to
- contain (explicit) homographs of things in the declaration. It works
- for accept_statements only because an accept_statement does not have
- a declarative_part.
-
- 18.o To avoid confusion, we use the term ``local to'' only
- informally in Ada 9X. Even RM83 used the term incorrectly (see, for
- example, RM83-12.3(13)).
-
- 18.p In Ada 83, (root) library units were inside Standard; it was
- not clear whether the declaration or body of Standard was meant. In
- Ada 9X, they are children of Standard, and so occur immediately
- within Standard's declarative region, but not within either the
- declaration or the body. (See RM83-8.6(2) and RM83-10.1.1(5).)
-
-
-
- 8.2 Scope of Declarations
-
- 1 [For each declaration, the language rules define a certain portion of the
- program text called the scope of the declaration. The scope of a declaration
- is also called the scope of any view or entity declared by the declaration.
- Within the scope of an entity, and only there, there are places where it is
- legal to refer to the declared entity. These places are defined by the rules
- of visibility and overloading.]
-
-
- Static Semantics
-
- 2 {immediate scope (of a declaration)} The immediate scope of a declaration
- is a portion of the declarative region immediately enclosing the declaration.
- The immediate scope starts at the beginning of the declaration, except in the
- case of an overloadable declaration, in which case the immediate scope starts
- just after the place where the profile of the callable entity is determined
- (which is at the end of the _specification for the callable entity, or at the
- end of the generic_instantiation if an instance).
-
- 2.a Reason: The reason for making overloadable declarations with
- profiles special is to simplify compilation: until the compiler has
- determined the profile, it doesn't know which other declarations are
- homographs of this one, so it doesn't know which ones this one should
- hide. Without this rule, two passes over the _specification or
- generic_instantiation would be required to resolve names that denote
- things with the same name as this one.
-
- The immediate scope extends to the end of the declarative region, with the
- following exceptions:
-
- 3 The immediate scope of a library_item includes only its semantic
- dependents.
-
- 3.a Reason: Section 10 defines only a partial ordering of library_
- items. Therefore, it is a good idea to restrict the immediate
- scope (and the scope, defined below) to semantic dependents.
-
- 3.b Consider also examples like this:
-
- 3.c package P is end P;
-
- 3.d package P.Q is
- I : Integer := 0;
- end P.Q;
-
- 3.e with P;
- package R is
- package X renames P;
- X.Q.I := 17; -- Illegal!
- end R;
-
- 3.f The scope of P.Q does not contain R. Hence, neither P.Q nor X.Q
- are visible within R. However, the name R.X.Q would be visible
- in some other library unit where both R and P.Q are visible
- (assuming R were made legal by removing the offending
- declaration).
-
- 4 The immediate scope of a declaration in the private part of a
- library unit does not include the visible part of any public
- descendant of that library unit. {descendant [relationship with
- scope]}
-
- 4.a Ramification: In other words, a declaration in the private part
- can be visible within the visible part, private part and body of
- a private child unit. On the other hand, such a declaration can
- be visible within only the private part and body of a public
- child unit.
-
- 4.b Reason: The purpose of this rule is to prevent children from
- giving private information to clients.
-
- 4.c Ramification: For a public child subprogram, this means that
- the parent's private part is not visible in the formal_parts of
- the declaration and of the body. This is true even for
- subprogram_bodies that are not completions. For a public child
- generic unit, it means that the parent's private part is not
- visible in the generic_formal_part, as well as in the first list
- of basic_declarative_items (for a generic package), or the
- formal_part(s) (for a generic subprogram).
-
- 5 {visible part} [The visible part of (a view of) an entity is a portion of
- the text of its declaration containing declarations that are visible from
- outside.] {private part [distributed]} The private part of (a view of) an
- entity that has a visible part contains all declarations within the
- declaration of (the view of) the entity, except those in the visible part;
- [these are not visible from outside. Visible and private parts are defined
- only for these kinds of entities: callable entities, other program units, and
- composite types.]
-
- 6 {visible part [of a view of a callable entity]} The visible part
- of a view of a callable entity is its profile.
-
- 7 {visible part [of a view of a composite type]} The visible part
- of a composite type other than a task or protected type consists
- of the declarations of all components declared [(explicitly or
- implicitly)] within the type_declaration.
-
- 8 {visible part [of a generic unit]} The visible part of a generic
- unit includes the generic_formal_part. For a generic package, it
- also includes the first list of basic_declarative_items of the
- package_specification. For a generic subprogram, it also
- includes the profile.
-
- 8.a Reason: Although there is no way to reference anything but the
- formals from outside a generic unit, they are still in the
- visible part in the sense that the corresponding declarations in
- an instance can be referenced (at least in some cases). In
- other words, these declarations have an effect on the outside
- world. The visible part of a generic unit needs to be defined
- this way in order to properly support the rule that makes a
- parent's private part invisible within a public child's visible
- part.
-
- 8.b Ramification: The visible part of an instance of a generic unit
- is as defined for packages and subprograms; it is not defined in
- terms of the visible part of a generic unit.
-
- 9 [The visible part of a package, task unit, or protected unit
- consists of declarations in the program unit's declaration other
- than those following the reserved word private, if any; see 7.1
- and 12.7 for packages, 9.1 for task units, and 9.4 for protected
- units.]
-
- 10 {scope (of a declaration)} The scope of a declaration always contains
- the immediate scope of the declaration. In addition, for a given declaration
- that occurs immediately within the visible part of an outer declaration, or
- is a public child of an outer declaration, the scope of the given declaration
- extends to the end of the scope of the outer declaration, except that the
- scope of a library_item includes only its semantic dependents.
-
- 10.a Ramification: Note the recursion. If a declaration appears
- in the visible part of a library unit, its scope extends to the end
- of the scope of the library unit, but since that only includes
- dependents of the declaration of the library unit, the scope of the
- inner declaration also only includes those dependents. If X renames
- library package P, which has a child Q, a with_clause mentioning P.Q
- is necessary to be able to refer to X.Q, even if P.Q is visible at
- the place where X is declared.
-
- 11 {immediate scope (of (a view of) an entity)} The immediate scope of a
- declaration is also the immediate scope of the entity or view declared by the
- declaration. {scope (of (a view of) an entity)} Similarly, the scope of a
- declaration is also the scope of the entity or view declared by the
- declaration.
-
- 11.a Ramification: The rule for immediate scope implies the
- following:
-
- 11.b If the declaration is that of a library unit, then the
- immediate scope includes the declarative region of the
- declaration itself, but not other places, unless they are
- within the scope of a with_clause that mentions the
- library unit.
-
- 11.c It is necessary to attach the semantics of with_
- clauses to [immediate] scopes (as opposed to visibility),
- in order for various rules to work properly. A library
- unit should hide a homographic implicit declaration that
- appears in its parent, but only within the scope of a
- with_clause that mentions the library unit. Otherwise,
- we would violate the "legality determinable via semantic
- dependences" rule of Section 10, ``Program Structure and
- Compilation Issues''. The declaration of a library unit
- should be allowed to be a homograph of an explicit
- declaration in its parent's body, so long as that body
- does not mention the library unit in a with_clause.
-
- 11.d This means that one cannot denote the declaration
- of the library unit, but one might still be able to
- denote the library unit via another view.
-
- 11.e A with_clause does not make the declaration of a
- library unit visible; the lack of a with_clause prevents
- it from being visible. Even if a library unit is
- mentioned in a with_clause, its declaration can still be
- hidden.
-
- 11.f The completion of the declaration of a library unit
- (assuming that's also a declaration) is not visible,
- neither directly nor by selection, outside that
- completion.
-
- 11.g The immediate scope of a declaration immediately within
- the body of a library unit does not include any child of
- that library unit.
-
- 11.h This is needed to prevent children from looking
- inside their parent's body. The children are in the
- declarative region of the parent, and they might be after
- the parent's body. Therefore, the scope of a declaration
- that occurs immediately within the body might include
- some children.
- NOTES
- 12 (4) There are notations for denoting visible declarations that are not
- directly visible. For example, parameter_specifications are in the
- visible part of a subprogram_declaration so that they can be used in
- named-notation calls appearing outside the called subprogram. For
- another example, declarations of the visible part of a package can be
- denoted by expanded names appearing outside the package, and can be made
- directly visible by a use_clause.
-
- 12.a Ramification: There are some obscure involving generics cases in
- which there is no such notation. See Section 12.
-
-
- Extensions to Ada 83
-
- 12.b {extensions to Ada 83} The fact that the immediate scope of an
- overloadable declaration does not include its profile is new to Ada
- 9X. It replaces RM83-8.3(16), which said that within a subprogram
- specification and within the formal part of an entry declaration or
- accept statement, all declarations with the same designator as the
- subprogram or entry were hidden from all visibility. The
- RM83-8.3(16) rule seemed to be overkill, and created both
- implementation difficulties and unnecessary semantic complexity.
-
- Wording Changes From Ada 83
-
- 12.c We no longer need to talk about the scope of notations,
- identifiers, character_literals, and operator_symbols.
-
- 12.d The notion of "visible part" has been extended in Ada 9X. The
- syntax of task and protected units now allows private parts, thus
- requiring us to be able to talk about the visible part as well. It
- was necessary to extend the concept to subprograms and to generic
- units, in order for the visibility rules related to child library
- units to work properly. It was necessary to define the concept
- separately for generic formal packages, since their visible part is
- slightly different from that of a normal package. Extending the
- concept to composite types made the definition of scope slightly
- simpler. We define visible part for some things elsewhere, since it
- makes a big difference to the user for those things. For composite
- types and subprograms, however, the concept is used only in arcane
- visibility rules, so we localize it to this clause.
-
- 12.e In Ada 83, the semantics of with_clauses was described in
- terms of visibility. It is now described in terms of [immediate]
- scope.
-
- 12.f We have clarified that the following is illegal (where Q and R
- are library units):
-
- 12.g package Q is
- I : Integer := 0;
- end Q;
-
- 12.h package R is
- package X renames Standard;
- X.Q.I := 17; -- Illegal!
- end R;
-
- 12.i even though Q is declared in the declarative region of
- Standard, because R does not mention Q in a with_clause.
-
-
-
- 8.3 Visibility
-
- 1 [{visibility rules} The visibility rules, given below, determine which
- declarations are visible and directly visible at each place within a program.
- The visibility rules apply to both explicit and implicit declarations.]
-
-
- Static Semantics
-
- 2 {visibility (direct)} {directly visible} {directly visible} A declaration
- is defined to be directly visible at places where a name consisting of only
- an identifier or operator_symbol is sufficient to denote the declaration;
- that is, no selected_component notation or special context (such as preceding
- => in a named association) is necessary to denote the declaration. {visible}
- A declaration is defined to be visible wherever it is directly visible, as
- well as at other places where some name (such as a selected_component) can
- denote the declaration.
-
- 3 The syntactic category direct_name is used to indicate contexts where
- direct visibility is required. The syntactic category selector_name is used
- to indicate contexts where visibility, but not direct visibility, is
- required.
-
- 4 {visibility (immediate)} {visibility (use clause)} There are two kinds of
- direct visibility: immediate visibility and use-visibility. {immediately
- visible} A declaration is immediately visible at a place if it is directly
- visible because the place is within its immediate scope. {use-visible} A
- declaration is use-visible if it is directly visible because of a use_clause
- (see 8.4). Both conditions can apply.
-
- 5 {hiding} A declaration can be hidden, either from direct visibility, or
- from all visibility, within certain parts of its scope. {hidden from all
- visibility} Where hidden from all visibility, it is not visible at all
- (neither using a direct_name nor a selector_name). {hidden from direct
- visibility} Where hidden from direct visibility, only direct visibility is
- lost; visibility using a selector_name is still possible.
-
- 6 [{overloaded} Two or more declarations are overloaded if they all have
- the same defining name and there is a place where they are all directly
- visible.]
-
- 6.a Ramification: Note that a name can have more than one possible
- interpretation even if it denotes a non-overloadable entity. For
- example, if there are two functions F that return records, both
- containing a component called C, then the name F.C has two possible
- interpretations, even though component declarations are not
- overloadable.
-
- 7 {overloadable} The declarations of callable entities [(including
- enumeration literals)] are overloadable[, meaning that overloading is allowed
- for them].
-
- 7.a Ramification: A generic_declaration is not overloadable within
- its own generic_formal_part. This follows from the rules about when
- a name denotes a current instance. See AI-00286. This implies that
- within a generic_formal_part, outer declarations with the same
- defining name are hidden from direct visibility. It also implies
- that if a generic formal parameter has the same defining name as the
- generic itself, the formal parameter hides the generic from direct
- visibility.
-
- 8 {homograph} Two declarations are homographs if they have the same
- defining name, and, if both are overloadable, their profiles are type
- conformant. {type conformance [partial]}[An inner declaration hides any
- outer homograph from direct visibility.]
-
- 9 [Two homographs are not generally allowed immediately within the same
- declarative region unless one overrides the other (see Legality Rules
- below).] {override} A declaration overrides another homograph that occurs
- immediately within the same declarative region in the following cases:
-
- 10 An explicit declaration overrides an implicit declaration of a
- primitive subprogram, [regardless of which declaration occurs
- first];
-
- 10.a Ramification: And regardless of whether the explicit
- declaration is overloadable or not.
-
- 10.b The ``regardless of which declaration occurs first'' is there
- because the explicit declaration could be a primitive subprogram
- of a partial view, and then the full view might inherit a
- homograph. We are saying that the explicit one wins (within its
- scope), even though the implicit one comes later.
-
- 10.c If the overriding declaration is also a subprogram, then it is a
- primitive subprogram.
-
- 10.d As explained in 7.3.1, ``Private Operations'', some inherited
- primitive subprograms are never declared. Such subprograms
- cannot be overridden, although they can be reached by
- dispatching calls in the case of a tagged type.
-
- 11 The implicit declaration of an inherited operator overrides that
- of a predefined operator;
-
- 11.a Ramification: In a previous version of Ada 9X, we tried to
- avoid the notion of predefined operators, and say that they were
- inherited from some magical root type. However, this seemed
- like too much mechanism. Therefore, a type can have a
- predefined "+" as well as an inherited "+". The above rule says
- the inherited one wins.
-
- 11.b The ``regardless of which declaration occurs first'' applies
- here as well, in the case where derived_type_declaration in the
- visible part of a public library unit derives from a private
- type declared in the parent unit, and the full view of the
- parent type has additional predefined operators, as explained in
- 7.3.1, ``Private Operations''. Those predefined operators can
- be overridden by inherited subprograms implicitly declared
- earlier.
-
- 12 An implicit declaration of an inherited subprogram overrides a
- previous implicit declaration of an inherited subprogram.
-
- 13 [For an implicit declaration of a primitive subprogram in a
- generic unit, there is a copy of this declaration in an
- instance.] However, a whole new set of primitive subprograms is
- implicitly declared for each type declared within the visible
- part of the instance. These new declarations occur immediately
- after the type declaration, and override the copied ones. [The
- copied ones can be called only from within the instance; the new
- ones can be called only from outside the instance, although for
- tagged types, the body of a new one can be executed by a call to
- an old one.]
-
- 13.a Discussion: In addition, this is also stated redundantly
- (again), and is repeated, in 12.3, ``Generic Instantiation''.
- The rationale for the rule is explained there.
-
- 14 {visible} {hidden from all visibility [distributed]} A declaration is
- visible within its scope, except where hidden from all visibility, as
- follows:
-
- 15 {hidden from all visibility [for overridden declaration]} An
- overridden declaration is hidden from all visibility within the
- scope of the overriding declaration.
- 15.a Ramification: We have to talk about the scope of the overriding
- declaration, not its visibility, because it hides even when it
- is itself hidden.
-
- 15.b Note that the scope of an explicit subprogram_declaration does
- not start until after its profile.
-
- 16 {hidden from all visibility [within the declaration itself]} A
- declaration is hidden from all visibility until the end of the
- declaration, except:
-
- 17 For a record type or record extension, the declaration is
- hidden from all visibility only until the reserved word
- record;
-
- 18 For a package_declaration, task declaration, protected
- declaration, generic_package_declaration, or subprogram_
- body, the declaration is hidden from all visibility only
- until the reserved word is of the declaration.
- {94-4942.a}
-
- 18.a Ramification: We're talking about the is of the construct
- itself, here, not some random is that might appear in a generic_
- formal_part.
-
- 19 {hidden from all visibility [for a declaration completed by a
- subsequent declaration]} If the completion of a declaration is a
- declaration, then within the scope of the completion, the first
- declaration is hidden from all visibility. Similarly, a
- discriminant_specification or parameter_specification is hidden
- within the scope of a corresponding discriminant_specification or
- parameter_specification of a corresponding completion, or of a
- corresponding accept_statement.
-
- 19.a Ramification: This rule means, for example, that within the
- scope of a full_type_declaration that completes a private_type_
- declaration, the name of the type will denote the full_type_
- declaration, and therefore the full view of the type. On the
- other hand, if the completion is not a declaration, then it
- doesn't hide anything, and you can't denote it.
-
- 20 {hidden from all visibility [by lack of a with_clause]} The
- declaration of a library unit (including a library_unit_renaming_
- declaration) is hidden from all visibility except at places that
- are within its declarative region or within the scope of a with_
- clause that mentions it. [For each declaration or renaming of a
- generic unit as a child of some parent generic package, there is
- a corresponding declaration nested immediately within each
- instance of the parent.] Such a nested declaration is hidden
- from all visibility except at places that are within the scope of
- a with_clause that mentions the child. {94-4933.a}
-
- 20.a Discussion: This is the rule that prevents with_clauses from
- being transitive; the [immediate] scope includes indirect
- semantic dependents.
-
- 21 {directly visible} {immediately visible} {visibility (direct)}
- {visibility (immediate)} A declaration with a defining_identifier or
- defining_operator_symbol is immediately visible [(and hence directly
- visible)] within its immediate scope {hidden from direct visibility
- [distributed]} except where hidden from direct visibility, as follows:
-
- 22 {hidden from direct visibility [by an inner homograph]} A
- declaration is hidden from direct visibility within the immediate
- scope of a homograph of the declaration, if the homograph occurs
- within an inner declarative region;
-
- 23 {hidden from direct visibility [where hidden from all
- visibility]} A declaration is also hidden from direct visibility
- where hidden from all visibility.
-
-
- Name Resolution Rules
-
- 24 {possible interpretation [for direct_names]} A direct_name shall resolve
- to denote a directly visible declaration whose defining name is the same as
- the direct_name. {possible interpretation [for selector_names]} A selector_
- name shall resolve to denote a visible declaration whose defining name is the
- same as the selector_name.
-
- 24.a Discussion: "The same as" has the obvious meaning here, so
- for +, the possible interpretations are declarations whose defining
- name is "+" (an operator_symbol).
-
- 25 These rules on visibility and direct visibility do not apply in a
- context_clause, a parent_unit_name, or a pragma that appears at the place of
- a compilation_unit. For those contexts, see the rules in 10.1.6,
- ``Environment-Level Visibility Rules''.
-
- 25.a Ramification: Direct visibility is irrelevant for character_
- literals. In terms of overload resolution character_literals are
- similar to other literals, like null -- see 4.2. For character_
- literals, there is no need to worry about hiding, since there is no
- way to declare homographs.
-
-
- Legality Rules
-
- 26 An explicit declaration is illegal if there is a homograph occurring
- immediately within the same declarative region that is visible at the place
- of the declaration, and is not hidden from all visibility by the explicit
- declaration. Similarly, the context_clause for a subunit is illegal if it
- mentions (in a with_clause) some library unit, and there is a homograph of
- the library unit that is visible at the place of the corresponding stub, and
- the homograph and the mentioned library unit are both declared immediately
- within the same declarative region. {generic contract issue [partial]} These
- rules also apply to dispatching operations declared in the visible part of an
- instance of a generic unit. However, they do not apply to other overloadable
- declarations in an instance[; such declarations may have type conformant
- profiles in the instance, so long as the corresponding declarations in the
- generic were not type conformant]. {type conformance [partial]}
-
- 26.a Discussion: Normally, these rules just mean you can't
- explicitly declare two homographs immediately within the same
- declarative region. The wording is designed to handle the following
- special cases:
-
- 26.b If the second declaration completes the first one, the
- second declaration is legal.
-
- 26.c If the body of a library unit contains an explicit
- homograph of a child of that same library unit, this is
- illegal only if the body mentions the child in its
- context_clause, or if some subunit mentions the child.
- Here's an example:
-
- 26.d package P is
- end P;
-
- 26.e package P.Q is
- end P.Q;
-
- 26.f package body P is
- Q : Integer; -- OK; we cannot see package P.Q here.
- procedure Sub is separate;
- end P;
-
- 26.g with P.Q;
- separate(P)
- procedure Sub is -- Illegal.
- begin
- null;
- end Sub;
-
- 26.h If package body P said "with P.Q;", then it would
- be illegal to declare the homograph Q: Integer. But it
- does not, so the body of P is OK. However, the subunit
- would be able to see both P.Q's, and is therefore
- illegal.
-
- 26.i A previous version of Ada 9X allowed the subunit,
- and said that references to P.Q would tend to be
- ambiguous. However, that was a bad idea, because it
- requires overload resolution to resolve references to
- directly visible non-overloadable homographs, which is
- something compilers have never before been required to
- do.
-
- 26.j Note that we need to be careful which things we make "hidden
- from all visibility" versus which things we make simply illegal for
- names to denote. The distinction is subtle. The rules that disallow
- names denoting components within a type declaration (see 3.7) do not
- make the components invisible at those places, so that the above rule
- makes components with the same name illegal. The same is true for
- the rule that disallows names denoting formal parameters within a
- formal_part (see 6.1).
-
- 26.k Discussion: The part about instances is from AI-00012. The
- reason it says ``overloadable declarations'' is because we don't want
- it to apply to type extensions that appear in an instance; components
- are not overloadable.
-
-
- NOTES
- 27 (5) Visibility for compilation units follows from the definition of the
- environment in 10.1.4, except that it is necessary to apply a with_
- clause to obtain visibility to a library_unit_declaration or library_
- unit_renaming_declaration.
-
- 28 (6) In addition to the visibility rules given above, the meaning of the
- occurrence of a direct_name or selector_name at a given place in the
- text can depend on the overloading rules (see 8.6). {94-4666.a}
-
- 29 (7) Not all contexts where an identifier, character_literal, or
- operator_symbol are allowed require visibility of a corresponding
- declaration. Contexts where visibility is not required are identified
- by using one of these three syntactic categories directly in a syntax
- rule, rather than using direct_name or selector_name.
-
- 29.a Ramification: An identifier, character_literal or operator_symbol
- that occurs in one of the following contexts is not required to
- denote a visible or directly visible declaration:
-
- 29.b A defining name.
-
- 29.c The identifiers or operator_symbol that appear after the
- reserved word end in a proper_body. Similarly for ``end
- loop'', etc.
-
- 29.d An attribute_designator.
-
- 29.e A pragma identifier.
-
- 29.f A pragma_argument_identifier.
-
- 29.g An identifier specific to a pragma used in a pragma
- argument.
-
- 29.h The visibility rules have nothing to do with the above cases; the
- meanings of such things are defined elsewhere. Reserved words are
- not identifiers; the visibility rules don't apply to them either.
-
- 29.i Because of the way we have defined "declaration", it is possible
- for a usage name to denote a subprogram_body, either within that
- body, or (for a non-library unit) after it (since the body hides the
- corresponding declaration, if any). Other bodies do not work that
- way. Completions of type_ and deferred_constant_declarations do work
- that way. Accept_statements are never denoted, although the
- parameter_specifications in their profiles can be.
-
- 29.j The scope of a subprogram does not start until after its profile.
- Thus, the following is legal:
-
- 29.k X : constant Integer := 17;
- ...
- package P is
- procedure X(Y : in Integer := X);
- end P;
-
- 29.l The body of the subprogram will probably be illegal, however, since
- the constant X will be hidden by then.
-
- 29.m The rule is different for generic subprograms, since they are not
- overloadable; the following is illegal:
-
- 29.n X : constant Integer := 17;
- package P is
- generic
- Z : Integer := X; -- Illegal!
- procedure X(Y : in Integer := X); -- Illegal!
- end P;
-
- {94-4942.a}
-
- 29.o The constant X is hidden from direct visibility by the generic
- declaration.
-
-
- Extensions to Ada 83
-
- 29.p {extensions to Ada 83} Declarations with the same defining
- name as that of a subprogram or entry being defined are nevertheless
- visible within the subprogram specification or entry declaration.
-
- Wording Changes From Ada 83
-
- 29.q The term ``visible by selection'' is no longer defined. We
- use the terms ``directly visible'' and ``visible'' (among other
- things). There are only two regions of text that are of interest,
- here: the region in which a declaration is visible, and the region in
- which it is directly visible.
-
- 29.r Visibility is defined only for declarations.
-
-
-
- 8.4 Use Clauses
-
- 1 [A use_package_clause achieves direct visibility of declarations that
- appear in the visible part of a package; a use_type_clause achieves direct
- visibility of the primitive operators of a type.]
-
-
- Language Design Principles
-
- 1.a {equivalence of use_clauses and selected_components} If and
- only if the visibility rules allow P.A, "use P;" should make A
- directly visible (barring name conflicts). This means, for example,
- that child library units, and generic formals of a formal package
- whose formal_package_actual_part is (<>), should be made visible by a
- use_clause for the appropriate package.
-
- 1.b {Beaujolais effect} The rules for use_clauses were carefully
- constructed to avoid so-called Beaujolais effects, where the addition
- or removal of a single use_clause, or a single declaration in a
- "use"d package, would change the meaning of a program from one legal
- interpretation to another.
-
- Syntax
-
- 2 use_clause ::= use_package_clause | use_type_clause
-
- 3 use_package_clause ::= use package_name {, package_name};
-
- 4 use_type_clause ::= use type subtype_mark {, subtype_mark};
-
-
- Legality Rules
-
- 5 A package_name of a use_package_clause shall denote a package.
-
- 5.a Ramification: This includes formal packages.
-
-
- Static Semantics
-
- 6 {scope (of a use_clause)} For each use_clause, there is a certain region
- of text called the scope of the use_clause. For a use_clause within a
- context_clause of a library_unit_declaration or library_unit_renaming_
- declaration, the scope is the entire declarative region of the declaration.
- For a use_clause within a context_clause of a body, the scope is the entire
- body [and any subunits (including multiply nested subunits). The scope does
- not include context_clauses themselves.]
-
- 7 For a use_clause immediately within a declarative region, the scope is
- the portion of the declarative region starting just after the use_clause and
- extending to the end of the declarative region. However, the scope of a use_
- clause in the private part of a library unit does not include the visible
- part of any public descendant of that library unit.
-
- 7.a Reason: The exception echoes the similar exception for
- ``immediate scope (of a declaration)'' (see 8.2). It makes use_
- clauses work like this:
-
- 7.b package P is
- type T is range 1..10;
- end P;
-
- 7.c with P;
- package Parent is
- private
- use P;
- X : T;
- end Parent;
-
- 7.d package Parent.Child is
- Y : T; -- Illegal!
- Z : P.T;
- private
- W : T;
- end Parent.Child;
-
- 7.e The declaration of Y is illegal because the scope of the ``use
- P'' does not include that place, so T is not directly visible there.
- The declarations of X, Z, and W are legal.
-
- 8 {potentially use-visible} For each package denoted by a package_name of a
- use_package_clause whose scope encloses a place, each declaration that occurs
- immediately within the declarative region of the package is potentially
- use-visible at this place if the declaration is visible at this place.
- {94-4666.b} For each type T or T'Class determined by a subtype_mark of a use_
- type_clause whose scope encloses a place, the declaration of each primitive
- operator of type T is potentially use-visible at this place if its
- declaration is visible at this place.
-
- 8.a Ramification: Primitive subprograms whose defining name is an
- identifier are not made potentially visible by a use_type_clause. A
- use_type_clause is only for operators.
-
- 8.b The semantics described here should be similar to the semantics
- for expanded names given in 4.1.3, ``Selected Components'' so as to
- achieve the effect requested by the ``principle of equivalence of
- use_clauses and selected_components.'' Thus, child library units and
- generic formal parameters of a formal package are potentially
- use-visible when their enclosing package is use'd.
-
- 8.c The "visible at that place" part implies that applying a use_
- clause to a parent unit does not make all of its children use-visible
- -- only those that have been made visible by a with_clause. It also
- implies that we don't have to worry about hiding in the definition of
- "directly visible" -- a declaration cannot be use-visible unless it
- is visible.
-
- 8.d Note that "use type T'Class;" is equivalent to "use type T;",
- which helps avoid breaking the generic contract model.
-
- 9 {use-visible} {visibility (use clause)} A declaration is use-visible if
- it is potentially use-visible, except in these naming-conflict cases:
-
- 10 A potentially use-visible declaration is not use-visible if the
- place considered is within the immediate scope of a homograph of
- the declaration.
-
- 11 Potentially use-visible declarations that have the same
- identifier are not use-visible unless each of them is an
- overloadable declaration.
-
- 11.a Ramification: Overloadable declarations don't cancel each other
- out, even if they are homographs, though if they are not
- distinguishable by formal parameter names or the presence or
- absence of default_expressions, any use will be ambiguous. We
- only mention identifiers here, because declarations named by
- operator_symbols are always overloadable, and hence never cancel
- each other. Direct visibility is irrelevant for character_
- literals.
- Dynamic Semantics
-
- 12 {elaboration [use_clause]} The elaboration of a use_clause has no
- effect.
-
-
- Examples
-
- 13 Example of a use clause in a context clause:
-
- 14 with Ada.Calendar; use Ada;
-
- 15 Example of a use type clause:
-
- 16 use type Rational_Numbers.Rational; -- see 7.1
- Two_Thirds: Rational_Numbers.Rational := 2/3;
-
- {94-4774.c}
-
- 16.a Ramification: In ``use X, Y;'', Y cannot refer to something
- made visible by the ``use'' of X. Thus, it's not (quite) equivalent
- to ``use X; use Y;''.
-
- 16.b If a given declaration is already immediately visible, then a
- use_clause that makes it potentially use-visible has no effect.
- Therefore, a use_type_clause for a type whose declaration appears in
- a place other than the visible part of a package has no effect; it
- cannot make a declaration use-visible unless that declaration is
- already immediately visible.
-
- 16.c "Use type S1;" and "use type S2;" are equivalent if S1 and S2
- are both subtypes of the same type. In particular, "use type S;" and
- "use type S'Base;" are equivalent.
-
- 16.d Reason: We considered adding a rule that prevented several
- declarations of views of the same entity that all have the same
- semantics from cancelling each other out. For example, if a
- (possibly implicit) subprogram_declaration for "+" is potentially
- use-visible, and a fully conformant renaming of it is also
- potentially use-visible, then they (annoyingly) cancel each other
- out; neither one is use-visible. The considered rule would have made
- just one of them use-visible. We gave up on this idea due to the
- complexity of the rule. It would have had to account for both
- overloadable and non-overloadable renaming_declarations, the case
- where the rule should apply only to some subset of the declarations
- with the same defining name, and the case of subtype_declarations
- (since they are claimed to be sufficient for renaming of subtypes).
-
-
- Extensions to Ada 83
-
- 16.e {extensions to Ada 83} The use_type_clause is new to Ada 9X.
-
- Wording Changes From Ada 83
-
- 16.f The phrase ``omitting from this set any packages that enclose
- this place'' is no longer necessary to avoid making something visible
- outside its scope, because we explicitly state that the declaration
- has to be visible in order to be potentially use-visible.
-
-
-
- 8.5 Renaming Declarations
-
- 1 [A renaming_declaration declares another name for an entity, such as an
- object, exception, package, subprogram, entry, or generic unit.
- Alternatively, a subprogram_renaming_declaration can be the completion of a
- previous subprogram_declaration.]
-
-
- Syntax
-
- 2 renaming_declaration ::=
- object_renaming_declaration
- | exception_renaming_declaration
- | package_renaming_declaration
- | subprogram_renaming_declaration
- | generic_renaming_declaration
-
-
- Dynamic Semantics
-
- 3 {elaboration [renaming_declaration]} The elaboration of a renaming_
- declaration evaluates the name that follows the reserved word renames and
- thereby determines the view and entity denoted by this name {renamed view}
- {renamed entity} (the renamed view and renamed entity). [A name that denotes
- the renaming_declaration denotes (a new view of) the renamed entity.]
-
-
- NOTES
- 4 (8) Renaming may be used to resolve name conflicts and to act as a
- shorthand. Renaming with a different identifier or operator_symbol does
- not hide the old name; the new name and the old name need not be visible
- at the same places.
-
- 5 (9) A task or protected object that is declared by an explicit object_
- declaration can be renamed as an object. However, a single task or
- protected object cannot be renamed since the corresponding type is
- anonymous (meaning it has no nameable subtypes). For similar reasons,
- an object of an anonymous array or access type cannot be renamed.
-
- 6 (10) A subtype defined without any additional constraint can be used to
- achieve the effect of renaming another subtype (including a task or
- protected subtype) as in
-
- 7 subtype Mode is Ada.Text_IO.File_Mode;
-
-
- Wording Changes From Ada 83
-
- 7.a The second sentence of RM83-8.5(3), ``At any point where a
- renaming declaration is visible, the identifier, or operator symbol
- of this declaration denotes the renamed entity.'' is incorrect. It
- doesn't say directly visible. Also, such an identifier might resolve
- to something else.
-
- 7.b The verbiage about renamings being legal ``only if exactly
- one...'', which appears in RM83-8.5(4) (for objects) and RM83-8.5(7)
- (for subprograms) is removed, because it follows from the normal
- rules about overload resolution. For language lawyers, these facts
- are obvious; for programmers, they are irrelevant, since failing
- these tests is highly unlikely.
-
-
-
- 8.5.1 Object Renaming Declarations
-
- 1 [An object_renaming_declaration is used to rename an object.]
-
-
- Syntax
-
- 2 object_renaming_declaration ::= defining_identifier : subtype_mark renames \
- object_name;
-
-
- Name Resolution Rules
-
- 3 The type of the object_name shall resolve to the type determined by the
- subtype_mark. {94-4500.a} {94-4505.a} {94-4506.a} {94-4507.a} {94-4509.a}
- {94-4532.a}
-
- 3.a Reason: A previous version of Ada 9X used the usual ``expected
- type'' wording: ``The expected type for the object_name is that
- determined by the subtype_mark.'' We changed it so that this would
- be illegal:
-
- 3.b X: T;
- Y: T'Class renames X; -- Illegal!
-
- 3.c When the above was legal, it was unclear whether Y was of type
- T or T'Class. Note that we still allow this:
-
- 3.d Z: T'Class := ...;
- W: T renames F(Z);
-
- 3.e where F is a function with a controlling parameter and result.
- This is admittedly a bit odd.
-
- 3.f Note that the matching rule for generic formal parameters of
- mode in out was changed to keep it consistent with the rule for
- renaming. That makes the rule different for in vs. in out.
-
- {94-5001.h}
-
-
- Legality Rules
-
- 4 The renamed entity shall be an object.
-
- 5 The renamed entity shall not be a subcomponent that depends on
- discriminants of a variable whose nominal subtype is unconstrained, unless
- this subtype is indefinite, or the variable is aliased. A slice of an array
- shall not be renamed if this restriction disallows renaming of the array.
-
- 5.a Reason: This prevents renaming of subcomponents that might
- disappear, which might leave dangling references. Similar
- restrictions exist for the Access attribute.
-
- 5.b Implementation Note: Note that if an implementation chooses to
- deallocate-then-reallocate on assignment_statements assigning to
- unconstrained definite objects, then it cannot represent renamings
- and access values as simple addresses, because the above rule does
- not apply to all components of such an object.
-
- 5.c Ramification: If it is a generic formal object, then the
- assume-the-best or assume-the-worst rules are applied as appropriate.
-
-
- Static Semantics
-
- 6 An object_renaming_declaration declares a new view [of the renamed
- object] whose properties are identical to those of the renamed view. [Thus,
- the properties of the renamed object are not affected by the renaming_
- declaration. In particular, its value and whether or not it is a constant
- are unaffected; similarly, the constraints that apply to an object are not
- affected by renaming (any constraint implied by the subtype_mark of the
- object_renaming_declaration is ignored).]
-
- 6.a Discussion: Because the constraints are ignored, it is a good
- idea to use the nominal subtype of the renamed object when writing an
- object_renaming_declaration.
-
-
- Examples
-
- 7 Example of renaming an object:
-
- 8 declare
- L : Person renames Leftmost_Person; -- see 3.10.1
- begin
- L.Age := L.Age + 1;
- end;
-
-
- Wording Changes From Ada 83
-
- 8.a The phrase ``subtype ... as defined in a corresponding object
- declaration, component declaration, or component subtype indica-
- tion,'' from RM83-8.5(5), is incorrect in Ada 9X; therefore we
- removed it. It is incorrect in the case of an object with an
- indefinite unconstrained nominal subtype.
-
-
-
- 8.5.2 Exception Renaming Declarations
-
- 1 [An exception_renaming_declaration is used to rename an exception.]
-
-
- Syntax
-
- 2 exception_renaming_declaration ::= defining_identifier : exception renames \
- exception_name;
-
-
- Legality Rules
-
- 3 The renamed entity shall be an exception.
-
-
- Static Semantics
-
- 4 An exception_renaming_declaration declares a new view [of the renamed
- exception].
-
-
- Examples
-
- 5 Example of renaming an exception:
-
- 6 EOF : exception renames Ada.IO_Exceptions.End_Error;-- see A.13
-
-
-
- 8.5.3 Package Renaming Declarations
-
- 1 [A package_renaming_declaration is used to rename a package.]
-
-
- Syntax
-
- 2 package_renaming_declaration ::= package defining_program_unit_name renames\
- package_name;
-
-
- Legality Rules
-
- 3 The renamed entity shall be a package.
-
-
- Static Semantics
-
- 4 A package_renaming_declaration declares a new view [of the renamed
- package].
-
-
- Examples
-
- 5 Example of renaming a package:
-
- 6 package TM renames Table_Manager;
-
-
-
- 8.5.4 Subprogram Renaming Declarations
-
- 1 A subprogram_renaming_declaration can serve as the completion of a
- subprogram_declaration; {renaming-as-body} such a renaming_declaration is
- called a renaming-as-body. {renaming-as-declaration} A subprogram_renaming_
- declaration that is not a completion is called a renaming-as-declaration[,
- and is used to rename a subprogram (possibly an enumeration literal) or an
- entry].
-
- 1.a Ramification: A renaming-as-body is a declaration, as defined
- in Section 3.
-
-
- Syntax
-
- 2 subprogram_renaming_declaration ::= subprogram_specification renames callab\
- le_entity_name;
-
-
- Name Resolution Rules
-
- 3 {expected profile [subprogram_renaming_declaration]} The expected profile
- for the callable_entity_name is the profile given in the subprogram_
- specification.
-
-
- Legality Rules
-
- 4 The profile of a renaming-as-declaration shall be mode-conformant with
- that of the renamed callable entity. {mode conformance (required)}
-
- 5 The profile of a renaming-as-body shall be subtype-conformant with that
- of the renamed callable entity, and shall conform fully to that of the
- declaration it completes. {subtype conformance (required)} {full conformance
- (required)} If the renaming-as-body completes that declaration before the
- subprogram it declares is frozen, the subprogram it declares takes its
- convention from the renamed subprogram; otherwise the convention of the
- renamed subprogram shall not be Intrinsic. {94-4774.b}
-
- 5.a Reason: The first part of the first sentence is to allow an
- implementation of a renaming-as-body as a single jump instruction to
- the target subprogram. Among other things, this prevents a
- subprogram from being completed with a renaming of an entry. (In
- most cases, the target of the jump can be filled in at link time. In
- some cases, such as a renaming of a name like "A(I).all", an indirect
- jump is needed. Note that the name is evaluated at renaming time,
- not at call time.)
-
- 5.b The second part of the first sentence is the normal rule for
- completions of subprogram_declarations.
-
- 5.c Ramification: An entry_declaration, unlike a subprogram_
- declaration, cannot be completed with a renaming_declaration. Nor
- can a generic_subprogram_declaration.
-
- 5.d The syntax rules prevent a protected subprogram declaration
- from being completed by a renaming. This is fortunate, because it
- allows us to avoid worrying about whether the implicit protected
- object parameter of a protected operation is involved in the
- conformance rules.
-
- 6 A name that denotes a formal parameter of the subprogram_specification is
- not allowed within the callable_entity_name.
-
- 6.a Reason: This is to prevent things like this:
-
- 6.b function F(X : Integer) return Integer renames Table(X).all;
-
- 6.c A similar rule in 6.1 forbids things like this:
-
- 6.d function F(X : Integer; Y : Integer := X) return Integer;
-
-
- Static Semantics
-
- 7 A renaming-as-declaration declares a new view of the renamed entity. The
- profile of this new view takes its subtypes, parameter modes, and calling
- convention from the original profile of the callable entity, while taking the
- formal parameter names and default_expressions from the profile given in the
- subprogram_renaming_declaration. The new view is a function or procedure,
- never an entry.
-
- 7.a To be honest: When renaming an entry as a procedure, the
- compile-time rules apply as if the new view is a procedure, but the
- run-time semantics of a call are that of an entry call.
-
- 7.b Ramification: For example, it is illegal for the entry_call_
- statement of a timed_entry_call to call the new view. But what looks
- like a procedure call will do things like barrier waiting.
-
-
- Dynamic Semantics
-
- 8 For a call on a renaming of a dispatching subprogram that is overridden,
- if the overriding occurred before the renaming, then the body executed is
- that of the overriding declaration, even if the overriding declaration is not
- visible at the place of the renaming; otherwise, the inherited or predefined
- subprogram is called.
-
- 8.a Discussion: Note that whether or not the renaming is itself
- primitive has nothing to do with the renamed subprogram.
-
- 8.b Note that the above rule is only for tagged types.
-
- 8.c Consider the following example:
-
- 8.d package P is
- type T is tagged null record;
- function Predefined_Equal(X, Y : T) return Boolean renames "=";
- private
- function "="(X, Y : T) return Boolean; -- Override predefined "\
- =".
- end P;
-
- 8.e with P; use P;
- package Q is
- function User_Defined_Equal(X, Y : T) return Boolean renames P.\
- "=";
- end Q;
-
- 8.f A call on Predefined_Equal will execute the predefined equality
- operator of T, whereas a call on User_Defined_Equal will execute the
- body of the overriding declaration in the private part of P.
-
- 8.g Thus a renaming allows one to squirrel away a copy of an
- inherited or predefined subprogram before later overriding it.
- {squirrel away (included in fairness to alligators)}
-
-
- NOTES
- 9 (11) A procedure can only be renamed as a procedure. A function whose
- defining_designator is either an identifier or an operator_symbol can be
- renamed with either an identifier or an operator_symbol; for renaming as
- an operator, the subprogram specification given in the renaming_
- declaration is subject to the rules given in 6.6 for operator
- declarations. Enumeration literals can be renamed as functions;
- similarly, attribute_references that denote functions (such as
- references to Succ and Pred) can be renamed as functions. An entry can
- only be renamed as a procedure; the new name is only allowed to appear
- in contexts that allow a procedure name. An entry of a family can be
- renamed, but an entry family cannot be renamed as a whole.
-
- 10 (12) The operators of the root numeric types cannot be renamed because
- the types in the profile are anonymous, so the corresponding
- specifications cannot be written; the same holds for certain attributes,
- such as Pos. {94-4666.c}
-
- 11 (13) Calls with the new name of a renamed entry are procedure_call_
- statements and are not allowed at places where the syntax requires an
- entry_call_statement in conditional_ and timed_entry_calls, nor in an
- asynchronous_select; similarly, the Count attribute is not available for
- the new name.
-
- 12 (14) The primitiveness of a renaming-as-declaration is determined by its
- profile, and by where it occurs, as for any declaration of (a view of) a
- subprogram; primitiveness is not determined by the renamed view. In
- order to perform a dispatching call, the subprogram name has to denote a
- primitive subprogram, not a non-primitive renaming of a primitive
- subprogram.
-
- 12.a Reason: A subprogram_renaming_declaration could more properly be
- called renaming_as_subprogram_declaration, since you're renaming
- something as a subprogram, but you're not necessarily renaming a
- subprogram. But that's too much of a mouthful. Or, alternatively,
- we could call it a callable_entity_renaming_declaration, but that's
- even worse. Not only is it a mouthful, it emphasizes the entity
- being renamed, rather than the new view, which we think is a bad
- idea. We'll live with the oddity.
-
-
- Examples
-
- 13 Examples of subprogram renaming declarations:
-
- 14 procedure My_Write(C : in Character) renames Pool(K).Write; -- see 4.1.3
-
- 15 function Real_Plus(Left, Right : Real ) return Real renames "+";
- function Int_Plus (Left, Right : Integer) return Integer renames "+";
-
- 16 function Rouge return Color renames Red; -- see 3.5.1
- function Rot return Color renames Red;
- function Rosso return Color renames Rouge;
-
- 17 function Next(X : Color) return Color renames Color'Succ; -- see 3.5.1
-
- 18 Example of a subprogram renaming declaration with new parameter names:
-
- 19 function "*" (X,Y : Vector) return Real renames Dot_Product; -- see 6.1
-
- 20 Example of a subprogram renaming declaration with a new default
- expression:
-
- 21 function Minimum(L : Link := Head) return Cell renames Min_Cell; -- see 6.1
-
-
-
- 8.5.5 Generic Renaming Declarations
-
- 1 [A generic_renaming_declaration is used to rename a generic unit.]
-
-
- Syntax
-
- 2 generic_renaming_declaration ::=
- generic package defining_program_unit_name renames generic_packag\
- e_name;
- | generic procedure defining_program_unit_name renames generic_proced\
- ure_name;
- | generic function defining_program_unit_name renames generic_functi\
- on_name;
-
-
- Legality Rules
-
- 3 The renamed entity shall be a generic unit of the corresponding kind.
-
-
- Static Semantics
-
- 4 A generic_renaming_declaration declares a new view [of the renamed
- generic unit].
-
-
- NOTES
- 5 (15) Although the properties of the new view are the same as those of
- the renamed view, the place where the generic_renaming_declaration
- occurs may affect the legality of subsequent renamings and
- instantiations that denote the generic_renaming_declaration, in
- particular if the renamed generic unit is a library unit (see 10.1.1).
-
-
- Examples
-
- 6 Example of renaming a generic unit:
-
- 7 generic package Enum_IO renames Ada.Text_IO.Enumeration_IO; -- see A.10.10
-
-
- Extensions to Ada 83
-
- 7.a {extensions to Ada 83} Renaming of generic units is new to Ada
- 9X. It is particularly important for renaming child library units
- that are generic units. For example, it might be used to rename
- Numerics.Generic_Elementary_Functions as simply Generic_Elementary_
- Functions, to match the name for the corresponding Ada-83-based
- package.
-
- Wording Changes From Ada 83
-
- 7.b The information in RM83-8.6, ``The Package Standard,'' has been
- updated for the child unit feature, and moved to Annex A, except for
- the definition of ``predefined type,'' which has been moved to 3.2.1.
-
-
-
- 8.6 The Context of Overload Resolution
-
- 1 [{overload resolution} Because declarations can be overloaded, it is
- possible for an occurrence of a usage name to have more than one possible
- interpretation; in most cases, ambiguity is disallowed. This clause
- describes how the possible interpretations resolve to the actual
- interpretation.
-
- 2 {overloading rules} Certain rules of the language (the Name Resolution
- Rules) are considered ``overloading rules''. If a possible interpretation
- violates an overloading rule, it is assumed not to be the intended
- interpretation; some other possible interpretation is assumed to be the
- actual interpretation. On the other hand, violations of non-overloading
- rules do not affect which interpretation is chosen; instead, they cause the
- construct to be illegal. To be legal, there usually has to be exactly one
- acceptable interpretation of a construct that is a ``complete context'', not
- counting any nested complete contexts.
-
- 3 {grammar (resolution of ambiguity)} The syntax rules of the language and
- the visibility rules given in 8.3 determine the possible interpretations.
- Most type checking rules (rules that require a particular type, or a
- particular class of types, for example) are overloading rules. Various rules
- for the matching of formal and actual parameters are overloading rules.]
-
-
- Language Design Principles
-
- 3.a The type resolution rules are intended to minimize the need for
- implicit declarations and preference rules associated with implicit
- conversion and dispatching operations.
-
- Name Resolution Rules
-
- 4 {complete context} [Overload resolution is applied separately to each
- complete context, not counting inner complete contexts.] Each of the
- following constructs is a complete context:
-
- 5 A context_item.
-
- 6 A declarative_item or declaration.
-
- 6.a Ramification: A loop_parameter_specification is a declaration,
- and hence a complete context.
-
- 7 A statement.
-
- 8 A pragma_argument_association.
-
- 8.a Reason: We would make it the whole pragma, except that certain
- pragma arguments are allowed to be ambiguous, and ambiguity
- applies to a complete context.
-
- 9 The expression of a case_statement.
-
- 9.a Ramification: This means that the expression is resolved
- without looking at the choices.
-
- 10 {interpretation (of a complete context)} {overall interpretation (of a
- complete context)} An (overall) interpretation of a complete context embodies
- its meaning, and includes the following information about the constituents of
- the complete context, not including constituents of inner complete contexts:
-
- 11 for each constituent of the complete context, to which syntactic
- categories it belongs, and by which syntax rules; and
-
- 11.a Ramification: Syntactic categories is plural here, because
- there are lots of trivial productions -- an expression might
- also be all of the following, in this order: identifier, name,
- primary, factor, term, simple_expression, and relation.
- Basically, we're trying to capture all the information in the
- parse tree here, without using compiler-writer's jargon like
- ``parse tree''.
-
- 12 for each usage name, which declaration it denotes (and,
- therefore, which view and which entity it denotes); and
-
- 12.a Ramification: In most cases, a usage name denotes the view
- declared by the denoted declaration. However, in certain cases,
- a usage name that denotes a declaration and appears inside the
- declarative region of that same declaration, denotes the current
- instance of the declaration. For example, within a task_body, a
- usage name that denotes the task_type_declaration denotes the
- object containing the currently executing task, and not the task
- type declared by the declaration.
-
- 13 for a complete context that is a declarative_item, whether or not
- it is a completion of a declaration, and (if so) which
- declaration it completes.
-
- 13.a Ramification: Unfortunately, we are not confident that the
- above list is complete. We'll have to live with that.
-
- 13.b To be honest: For ``possible'' interpretations, the above
- information is tentative.
-
- 13.c Discussion: A possible interpretation (an input to overload
- resolution) contains information about what a usage name might
- denote, but what it actually does denote requires overload resolution
- to determine. Hence the term ``tentative'' is needed for possible
- interpretations; otherwise, the definition would be circular.
-
- 14 {possible interpretation} A possible interpretation is one that obeys
- the syntax rules and the visibility rules. {acceptable interpretation}
- {resolve (overload resolution)} {interpretation (overload resolution)} An
- acceptable interpretation is a possible interpretation that obeys the
- overloading rules[, that is, those rules that specify an expected type or
- expected profile, or specify how a construct shall resolve or be
- interpreted.]
-
- 14.a To be honest: One rule that falls into this category, but
- does not use the above-mentioned magic words, is the rule about
- numbers of parameter associations in a call (see 6.4).
-
- 14.b Ramification: The Name Resolution Rules are the ones that
- appear under the Name Resolution Rules heading. Some Syntax Rules
- are written in English, instead of BNF. No rule is a Syntax Rule or
- Name Resolution Rule unless it appears under the appropriate heading.
-
- 15 {interpretation (of a constituent of a complete context)} The
- interpretation of a constituent of a complete context is determined from the
- overall interpretation of the complete context as a whole. [Thus, for
- example, ``interpreted as a function_call,'' means that the construct's
- interpretation says that it belongs to the syntactic category function_call.]
-
- 16 {denote} [Each occurrence of] a usage name denotes the declaration
- determined by its interpretation. It also denotes the view declared by its
- denoted declaration, except in the following cases:
-
- 16.a Ramification: As explained below, a pragma argument is
- allowed to be ambiguous, so it can denote several declarations, and
- all of the views declared by those declarations.
-
- 17 {current instance (of a type)} If a usage name appears within the
- declarative region of a type_declaration and denotes that same
- type_declaration, then it denotes the current instance of the
- type (rather than the type itself). The current instance of a
- type is the object or value of the type that is associated with
- the execution that evaluates the usage name.
-
- 17.a Reason: This is needed, for example, for references to the
- Access attribute from within the type_declaration. Also, within
- a task_body or protected_body, we need to be able to denote the
- current task or protected object. (For a single_task_
- declaration or single_protected_declaration, the rule about
- current instances is not needed.)
-
- 18 {current instance (of a generic unit)} If a usage name appears
- within the declarative region of a generic_declaration (but not
- within its generic_formal_part) and it denotes that same generic_
- declaration, then it denotes the current instance of the generic
- unit (rather than the generic unit itself). See also 12.3.
-
- 18.a To be honest: The current instance of a generic unit is the
- instance created by whichever generic_instantiation is of
- interest at any given time.
-
- 18.b Ramification: Within a generic_formal_part, a name that denotes
- the generic_declaration denotes the generic unit, which implies
- that it is not overloadable.
-
- 19 A usage name that denotes a view also denotes the entity of that view.
-
- 19.a Ramification: Usually, a usage name denotes only one
- declaration, and therefore one view and one entity.
-
- 20 {expected type [distributed]} The expected type for a given expression,
- name, or other construct determines, according to the type resolution rules
- given below, the types considered for the construct during overload
- resolution. {type resolution rules} [The type resolution rules provide
- support for class-wide programming, universal numeric literals, dispatching
- operations, and anonymous access types:]
-
- 20.a Ramification: Expected types are defined throughout the RM9X.
- The most important definition is that, for a subprogram, the expected
- type for the actual parameter is the type of the formal parameter.
-
- 20.b The type resolution rules are trivial unless either the actual
- or expected type is universal, class-wide, or of an anonymous access
- type.
-
- 21 {type resolution rules [if any type in a specified class of types
- is expected]} {type resolution rules [if expected type is
- universal or class-wide]} If a construct is expected to be of any
- type in a class of types, or of the universal or class-wide type
- for a class, then the type of the construct shall resolve to a
- type in that class or to a universal type that covers the class.
-
- 21.a Ramification: This matching rule handles (among other things)
- cases like the Val attribute, which denotes a function that
- takes a parameter of type universal_integer.
-
- 21.b The last part of the rule, ``or to a universal type that
- includes the class'' implies that if the expected type for an
- expression is universal_fixed, then an expression whose type is
- universal_real (such as a real literal) is OK.
-
- 22 {type resolution rules [if expected type is specific]} If the
- expected type for a construct is a specific type T, then the type
- of the construct shall resolve either to T, or:
-
- 22.a Ramification: {Beaujolais effect [partial]} This rule is not
- intended to create a preference for the specific type -- such a
- preference would cause Beaujolais effects.
-
- 23 to T'Class; or
-
- 23.a Ramification: This will only be legal as part of a call on a
- dispatching operation; see 3.9.2, ``Dispatching Operations of
- Tagged Types''. Note that that rule is not a Name Resolution
- Rule.
-
- 24 to a universal type that covers T; or
-
- 25 when T is an anonymous access type (see 3.10) with
- designated type D, to an access-to-variable type whose
- designated type is D'Class or is covered by D.
-
- 25.a Ramification: Because it says ``access-to-variable'' instead of
- ``access-to-object,'' two subprograms that differ only in that
- one has a parameter of an access-to-constant type, and the other
- has an access parameter, are distinguishable during overload
- resolution.
-
- 25.b The case where the actual is access-to-D'Class will only be
- legal as part of a call on a dispatching operation; see 3.9.2,
- ``Dispatching Operations of Tagged Types''. Note that that rule
- is not a Name Resolution Rule.
-
- 26 {expected profile [distributed]} In certain contexts, [such as in a
- subprogram_renaming_declaration,] the Name Resolution Rules define an
- expected profile for a given name; {profile resolution rule (name with a
- given expected profile)} in such cases, the name shall resolve to the name of
- a callable entity whose profile is type conformant with the expected profile.
- {type conformance (required)}
-
- 26.a Ramification: The parameter and result subtypes are not used
- in overload resolution. Only type conformance of profiles is
- considered during overload resolution. Legality rules generally
- require at least mode-conformance in addition, but those rules are
- not used in overload resolution.
-
-
- Legality Rules
-
- 27 {single (class expected type)} When the expected type for a construct is
- required to be a single type in a given class, the type expected for the
- construct shall be determinable solely from the context in which the
- construct appears, excluding the construct itself, but using the requirement
- that it be in the given class; the type of the construct is then this single
- expected type. Furthermore, the context shall not be one that expects any
- type in some class that contains types of the given class; in particular, the
- construct shall not be the operand of a type_conversion.
-
- 27.a Ramification: For example, the expected type for the literal
- null is required to be a single access type. But the expected type
- for the operand of a type_conversion is any type. Therefore, the
- literal null is not allowed as the operand of a type_conversion.
- This is true even if there is only one access type in scope. The
- reason for these rules is so that the compiler will not have to
- search ``everywhere'' to see if there is exactly one type in a class
- in scope.
-
- 28 A complete context shall have at least one acceptable interpretation; if
- there is exactly one, then that one is chosen.
-
- 28.a Ramification: This, and the rule below about ambiguity, are
- the ones that suck in all the Syntax Rules and Name Resolution Rules
- as compile-time rules. Note that this and the ambiguity rule have to
- be Legality Rules.
-
- 29 {preference (for root numeric operators and ranges)} There is a
- preference for the primitive operators (and ranges) of the root numeric types
- root_integer and root_real. In particular, if two acceptable interpretations
- of a constituent of a complete context differ only in that one is for a
- primitive operator (or range) of the type root_integer or root_real, and the
- other is not, the interpretation using the primitive operator (or range) of
- the root numeric type is preferred.
-
- 29.a Reason: The reason for this preference is so that