Ada Reference Manual (Ada 2022)Legal Information
Contents   Index   References   Search   Previous   Next 

3.10.2 Operations of Access Types

1
The attribute Access is used to create access values designating aliased objects and nonintrinsic subprograms. The “accessibility” rules prevent dangling references (in the absence of uses of certain unchecked features — see Clause 13). 

Name Resolution Rules

2/2
For an attribute_reference with attribute_designator Access (or Unchecked_Access — see 13.10), the expected type shall be a single access type A such that: 
2.1/2
A is an access-to-object type with designated type D and the type of the prefix is D'Class or is covered by D, or
2.2/2
A is an access-to-subprogram type whose designated profile is type conformant with that of the prefix. 
2.3/2
 The prefix of such an attribute_reference is never interpreted as an implicit_dereference or a parameterless function_call (see 4.1.4). The designated type or profile of the expected type of the attribute_reference is the expected type or profile for the prefix.

Static Semantics

3/5
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 certain construct (called a master construct), such as a subprogram_body. An accessibility level is deeper than another if it is more deeply nested at run time. 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
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.
5/5
Each master, and each entity and view created by it, has an accessibility level; when two levels are defined to be the same, the accessibility levels of the two associated entities are said to be tied to each other. Accessibility levels are defined as follows: 
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/5
An entity or view defined by a declaration and created as part of its elaboration has the same accessibility level as the innermost master of the declaration except in the cases of renaming and derived access types described below. A formal parameter of a callable entity has the same accessibility level as the master representing the invocation of the entity. 
8/5
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, unless the renaming is of a formal subprogram, in which case the accessibility level is that of the instance.
9/2
The accessibility level of a view conversion, qualified_expression, or parenthesized expression, is the same as that of the operand.
9.1/5
The accessibility level of a conditional_expression (see 4.5.7) is the accessibility level of the evaluated dependent_expression.
9.2/5
The accessibility level of a declare_expression (see 4.5.9) is the accessibility level of the body_expression.
10/4
The accessibility level of an aggregate that is used (in its entirety) to directly initialize part of an object is that of the object being initialized. In other contexts, the accessibility level of an aggregate is that of the innermost master that evaluates the aggregate. Corresponding rules apply to a value conversion (see 4.6).
10.1/3
The accessibility level of the result of a function call is that of the master of the function call, which is determined by the point of call as follows:
10.2/5
If the result type at the point of the function (or access-to-function type) declaration is a composite type, and the result is used (in its entirety) to directly initialize part of an object, the master is that of the object being initialized. In the case where the initialized object is a coextension (see below) that becomes a coextension of another object, the master is that of the eventual object to which the coextension will be transferred.
10.3/5
If the result is of an anonymous access type and is converted to a (named or anonymous) access type, the master is determined following the rules given below for determining the master of an object created by an allocator (even if the access result is of an access-to-subprogram type);
10.4/5
This paragraph was deleted.
10.5/5
If the call itself defines the result of a function F, or has an accessibility level that is tied to the result of such a function F, then the master of the call is that of the master of the call invoking F;
10.6/3
In other cases, the master of the call is that of the innermost master that evaluates the function call.
10.7/3
In the case of a call to a function whose result type is an anonymous access type, the accessibility level of the type of the result of the function call is also determined by the point of call as described above.
10.8/3
Within a return statement, the accessibility level of the return object is that of the execution of the return statement. If the return statement completes normally by returning from the function, then prior to leaving the function, the accessibility level of the return object changes to be a level determined by the point of call, as does the level of any coextensions (see below) of the return object.
11
The accessibility level of a derived access type is the same as that of its ultimate ancestor.
11.1/2
The accessibility level of the anonymous access type defined by an access_definition of an object_renaming_declaration is the same as that of the renamed view.
11.2/5
The accessibility level of the anonymous access type defined by an access_definition of a loop_parameter_subtype_indication is that of the loop parameter.
12/2
The accessibility level of the anonymous access type of an access discriminant in the subtype_indication or qualified_expression of an allocator, or in the expression or return_subtype_indication of a return statement is determined as follows:
12.1/2
If the value of the access discriminant is determined by a discriminant_association in a subtype_indication, the accessibility level of the object or subprogram designated by the associated value (or library level if the value is null); 
12.2/3
If the value of the access discriminant is determined by a default_expression in the declaration of the discriminant, the level of the object or subprogram designated by the associated value (or library level if null); 
12.3/3
If the value of the access discriminant is determined by a record_component_association in an aggregate, the accessibility level of the object or subprogram designated by the associated value (or library level if the value is null);
12.4/3
In other cases, where the value of the access discriminant is determined by an object with an unconstrained nominal subtype, the accessibility level of the object.
12.5/3
The accessibility level of the anonymous access type of an access discriminant in any other context is that of the enclosing object.
13/3
The accessibility level of the anonymous access type of an access parameter specifying an access-to-object type is the same as that of the view designated by the actual (or library-level if the actual is null). 
13.1/2
The accessibility level of the anonymous access type of an access parameter specifying an access-to-subprogram type is deeper than that of any master; all such anonymous access types have this same level. 
13.2/4
The accessibility level of the anonymous access subtype defined by a return_subtype_indication that is an access_definition (see 6.5) is that of the result subtype of the enclosing function.
13.3/4
The accessibility level of the type of a stand-alone object of an anonymous access-to-object type is the same as the accessibility level of the type of the access value most recently assigned to the object; accessibility checks ensure that this is never deeper than that of the declaration of the stand-alone object.
14/3
The accessibility level of an object created by an allocator is the same as that of the access type, except for an allocator of an anonymous access type (an anonymous allocator) in certain contexts, as follows: For an anonymous allocator that defines the result of a function with an access result, the accessibility level is determined as though the allocator were in place of the call of the function; in the special case of a call that is the operand of a type conversion, the level is that of the target access type of the conversion. For an anonymous allocator defining the value of an access parameter, the accessibility level is that of the innermost master of the call. For an anonymous allocator whose type is that of a stand-alone object of an anonymous access-to-object type, the accessibility level is that of the declaration of the stand-alone object. For one defining an access discriminant, the accessibility level is determined as follows:
14.1/3
for an allocator used to define the discriminant of an object, the level of the object;
14.2/3
for an allocator used to define the constraint in a subtype_indication in any other context, the level of the master that elaborates the subtype_indication.
14.3/3
This paragraph was deleted.
14.4/3
In the first case, the allocated object is said to be a coextension of the object whose discriminant designates it, as well as of any object of which the discriminated object is itself a coextension or subcomponent. If the allocated object is a coextension of an anonymous object representing the result of an aggregate or function call that is used (in its entirety) to directly initialize a part of an object, after the result is assigned, the coextension becomes a coextension of the object being initialized and is no longer considered a coextension of the anonymous object. All coextensions of an object (which have not thus been transfered by such an initialization) are finalized when the object is finalized (see 7.6.1).
14.5/3
Within a return statement, the accessibility level of the anonymous access type of an access result is that of the master of the call.
15/3
The accessibility level of a view of an object or subprogram designated by 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. 
16.1/5
  In the above rules, the operative constituents of a name or expression (see 4.4) are considered to be used in a given context if the enclosing name or expression is used in that context.
17
One accessibility level is defined to be statically deeper than another in the following cases: 
18/5
For a master construct that is statically nested within another master construct, the accessibility level of the inner master construct is statically deeper than that of the outer master construct.
18.1/2
The accessibility level of the anonymous access type of an access parameter specifying an access-to-subprogram type is statically deeper than that of any master; all such anonymous access types have this same level. 
19/5
The statically deeper relationship does not apply to the accessibility level of the following:
19.1/5
the anonymous type of an access parameter specifying an access-to-object type;
19.2/5
the type of a stand-alone object of an anonymous access-to-object type;
19.3/5
a raise_expression;
19.4/5
a descendant of a generic formal type;
19.5/5
a descendant of a type declared in a generic formal package. 
19.6/5
When the statically deeper relationship does not apply, the accessibility level is not considered to be statically deeper, nor statically shallower, than any other.
19.7/5
This paragraph was deleted.
19.8/5
When within a function body or the return expression of an expression function, the accessibility level of the master representing an execution of the function is statically deeper than that of the master of the function call invoking that execution, independent of how the master of the function call is determined (see above).
20/5
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; runtime checks are required in the case of more deeply nested instantiations.
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. 
21.1/5
  Notwithstanding other rules given above, the accessibility level of an entity that is tied to that of an explicitly aliased formal parameter of an enclosing function is considered (both statically and dynamically) to be the same as that of an entity whose accessibility level is tied to that of the return object of that function.
22
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. 
23
The following attribute is defined for a prefix X that denotes an aliased view of an object: 
24/1
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. 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. 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 with designated type D
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.
26/3
The view shall not be a subcomponent that depends on discriminants of an object unless the object is known to be constrained.
27/2
If A is a named access type and D is a tagged type, then the type of the view shall be covered by D; if A is anonymous and D is tagged, then the type of the view shall be either D'Class or a type covered by D; if D is untagged, then the type of the view shall be D, and either: 
27.1/2
the designated subtype of A shall statically match the nominal subtype of the view; or
27.2/4
D shall be discriminated in its full view and unconstrained in any partial view, and the designated subtype of A shall be unconstrained. 
28/3
The accessibility level of the view shall not be statically deeper than that of the access type A.
28.1/3
In addition to the places where Legality Rules normally apply (see 12.3), these requirements apply also in the private part of an instance of a generic unit.
29
A check is made that the accessibility level of X is not deeper than that of the access type A. If this check fails, Program_Error is raised.
30/5
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 can 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/5
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. The accessibility level of P shall not be statically deeper than that of S. If S is nonblocking, P shall be nonblocking. 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. The profile of P shall be subtype conformant with the designated profile of S, and shall not be Intrinsic. If the subprogram denoted by P is declared within a generic unit, and the expression P'Access occurs within the body of that generic unit or within the body of a generic unit declared within the declarative region of the generic unit, then the ultimate ancestor of S shall be either a nonformal type declared within the generic unit or an anonymous access type of an access parameter.

Legality Rules

32.1/3
  An expression is said to have distributed accessibility if it is
32.2/3
a conditional_expression (see 4.5.7); or
32.3/5
a declare_expression (see 4.5.9) whose body_expression has distributed accessibility; or
32.4/5
a view conversion, qualified_expression, or parenthesized expression whose operand has distributed accessibility.
32.5/5
  The statically deeper relationship does not apply to the accessibility level of an expression having distributed accessibility; that is, such an accessibility level is not considered to be statically deeper, nor statically shallower, than any other.
32.6/5
  Any static accessibility requirement that is imposed on an expression that has distributed accessibility (or on its type) is instead imposed on the dependent_expressions of the underlying conditional_expression. This rule is applied recursively if a dependent_expression also has distributed accessibility.
33
NOTE 1   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/2
NOTE 2   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). Named access types have predefined equality operators; anonymous access types do not, but they can use the predefined equality operators for universal_access (see 4.5.2). 
35
NOTE 3   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
NOTE 4   A call through the dereference of an access-to-subprogram value is never a dispatching call. 
37/5
NOTE 5   The Access attribute for subprograms and parameters of an anonymous access-to-subprogram type can be used together to implement “downward closures” — that is, to pass a more-nested subprogram as a parameter to a less-nested subprogram, as can be appropriate for an iterator abstraction or numerical integration. Downward closures can also be implemented using generic formal subprograms (see 12.6). Unlike for objects, there is no Unchecked_Access attribute for subprograms.
38/5
NOTE 6   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/5
NOTE 7   An implementation can consider two access-to-subprogram values to be unequal, even though they designate the same subprogram. For instance, this can happen 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

Examples

40
Example of use of the Access attribute: 
41/5
Becky : Person_Name := new Person(F);       -- see 3.10.1
Cars  : array (1..2) of aliased Car;
   ...
Becky.Vehicle := Cars(1)'Access;
Casey.Vehicle := Cars(2)'Access;

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe