Contents Index Previous Next
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).
Name Resolution Rules
2
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.
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.
Static Semantics
3
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. 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
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.
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
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.
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.
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.
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
- 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.
27/1
- 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 A's designated
subtype shall either statically match the nominal subtype of the view
or be discriminated and unconstrained;
28
- The accessibility level of the view shall not be statically
deeper than that of the access type 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.
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
- 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. The accessibility level of P shall not be statically
deeper than that of S. 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. If
the subprogram denoted by P is declared within a generic body, S
shall be declared within the generic body.
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 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 (see 4.5.2).
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.
37
85 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.
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;
Contents Index Previous Next Legal