4.8. Allocators

[PREVIOUS][UP][NEXT]

The evaluation of an allocator creates an object and yields an access value that designates the object.

    allocator ::=
       new subtype_indication | new qualified_expression                                                    

The type of the object created by an allocator is the base type of the type mark given in either the subtype indication or the qualified expression. For an allocator with a qualified expression, this expression defines the initial value of the created object. The type of the access value returned by an allocator must be determinable solely from the context, but using the fact that the value returned is of an access type having the named designated type.

The only allowed forms of constraint in the subtype indication of an allocator are index and discriminant constraints. If an allocator includes a subtype indication and if the type of the object created is an array type or a type with discriminants that do not have default expressions, then the subtype indication must either denote a constrained subtype, or include an explicit index or discriminant constraint.

If the type of the created object is an array type or a type with discriminants, then the created object is always constrained. If the allocator includes a subtype indication, the created object is constrained either by the subtype or by the default discriminant values. If the allocator includes a qualified expression, the created object is constrained by the bounds or discriminants of the initial value. For other types, the subtype of the created object is the subtype defined by the subtype indication of the access type definition.

For the evaluation of an allocator, the elaboration of the subtype indication or the evaluation of the qualified expression is performed first. The new object is then created. Initializations are then performed as for a declared object (see 3.2.1); the initialization is considered explicit in the case of a qualified expression; any initializations are implicit in the case of a subtype indication. Finally, an access value that designates the created object is returned.

An implementation must guarantee that any object created by the evaluation of an allocator remains allocated for as long as this object or one of its subcomponents is accessible directly or indirectly, that is, as long as it can be denoted by some name. Moreover, if an object or one of its subcomponents belongs to a task type, it is considered to be accessible as long as the task is not terminated. An implementation may (but need not) reclaim the storage occupied by an object created by an allocator, once this object has become inaccessible.

When an application needs closer control over storage allocation for objects designated by values of an access type, such control may be achieved by one or more of the following means:

  1. The total amount of storage available for the collection of objects of an access type can be set by means of a length clause (see 13.2).

  2. The pragma CONTROLLED informs the implementation that automatic storage reclamation must not be performed for objects designated by values of the access type, except upon leaving the innermost block statement, subprogram body, or task body that encloses the access type declaration, or after leaving the main program.

    pragma CONTROLLED (access_type_simple_name);

    A pragma CONTROLLED for a given access type is allowed at the same places as a representation clause for the type (see 13.1). This pragma is not allowed for a derived type.

  3. The explicit deallocation of the object designated by an access value can be achieved by calling a procedure obtained by instantiation of the predefined generic library procedure UNCHECKED_DEALLOCATION (see 13.10.1).

The exception STORAGE_ERROR is raised by an allocator if there is not enough storage. Note also that 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.

Examples (for access types declared in section 3.8):

 new CELL'(0, null, null)                          -- initialized explicitly
 new CELL'(VALUE => 0, SUCC => null, PRED => null) -- initialized explicitly
 new CELL                                          -- not initialized

 new MATRIX(1 .. 10, 1 .. 20)                  -- the bounds only are given
 new MATRIX'(1 .. 10 => (1 .. 20 => 0.0))      -- initialized explicitly

 new BUFFER(100)                          -- the discriminant only is given

 new BUFFER'(SIZE => 80, POS => 0, VALUE => (1 .. 80 => 'A'))
                                               -- initialized explicitly

References: access type, access type definition, access value, array type, block statement, bound of an array, collection, constrained subtype, constraint, constraint_error exception, context of overload resolution, derived type, designate, discriminant, discriminant constraint, elaboration, evaluation of a qualified expression, generic procedure, index constraint, initial value, initialization, instantiation, length clause, library unit, main program, name, object, object declaration, pragma, procedure, qualified expression, raising of exceptions, representation clause, simple name, storage_error exception, subcomponent, subprogram body, subtype, subtype indication, task body, task type, terminated task, type, type declaration, type mark, type with discriminants.


[INDEX][CONTENTS]