Section 12.1 - Declaring Access Types
It is often very useful to have a variable that, instead of storing
a value, stores a reference to some other object.
Such variables are called access variables in Ada, and
are essentially equivalent to pointers or references in other languages.
One common use of access variables is to implement items of varying size.
To create such variables, first create a type for it; these types are
called access types.
Here's an example of an access type declaration,
declaring that variables of type Node_Access
can access (reference) objects of type Node:
type Node_Access is access Node;
Here is the
BNF for creating an access type to an object:
access_object_type_declaration ::= "type" new_type_name "is"
"access" ["all"] type_name ";"
Variables with an access type can either refer to an object or be
null.
You can make an access variable null by assigning it the value of the
keyword "null", and you can check if it's null by comparing the variable
(using "=" or "/=") to "null".
Basically, you can treat "null" as a special value that any access type
can store.
The ability to "point" at other values is useful and efficient, but it
can also be dangerous.
It's easy to do the wrong thing with pointers and cause surprising results.
Ada tries to limit the damage that you can do while maintaining efficiency.
Ada does this through the following rules:
-
All access type variables are initialized as null (unless you specifically
initialize them to something else).
-
All operations that use what an access value references first check
to see if the access value is null.
If the access value is null, the exception Constraint_Error is raised.
-
Normally access-to-object types are limited to referring to
objects ``created dynamically'', as we will discuss next.
You must add the keyword ``all'' in the access type definition
to permit an access type to refer
to all objects of a given type; such access values are called
general access objects and are new to Ada 95.
One use for general access objects is to interface with C or C++ programs,
since C and C++ pointers are essentially equivalent to
Ada general access objects.
Another important use for general access objects is for object-oriented
programming, as we'll discuss later.
- "Arithmetic" is not permitted on access variables.
This is like Java and Pascal, which do not permit pointer arithmetic, and
unlike C and C++, which do support pointer arithmetic.
If you desparately need it, Ada does have a way to do pointer arithmetic
(see
package
System in LRM 13.7)
but its use is strongly discouraged in most circumstances.
The Ada compiler will optimize these checks and initializations away
if it can determine that they're unnecessary.
You can also turn off these checks for a given subprogram if you know
that that particular subprogram is totally correct.
Now that we know how to declare access types, let's see how we can use them.
Quiz:
Which of the following will define an access type named Thing_Access?
- type Thing_Access is access Thing;
- type access is Thing_Access;
- Thing_Access is access type;
You may also:
David A. Wheeler (dwheeler@ida.org)