Ada Programming/Memory - eMyTextBooks

Search:  

Free online books - just read it!

See live article   •   Ada Programming/Memory
 

Ada Programming/Types/access (Redirected from Ada Programming/Memory)


Table of contents


Different access types

Pool access

Handles an access to an object which was created on one specific heap (or storage pool as it is called in Ada). May not point to a stack or library level (static) object.

type Day_Of_Month is range 1 .. 31;
type Day_Of_Month_Access is access Day_Of_Month;

Access all

Handles an access to an object which was created on any storage pool, on the stack or at library level (static).

type Day_Of_Month is range 1 .. 31;            
type Day_Of_Month_Access is access all Day_Of_Month;

Access constant

Handles an access either to a constant or variable object which was created on any storage pool, on the stack or at library level (static), but with a restriction to read-only usage of the referenced object, whether it be intrinsically a constant or a variable.

type Day_Of_Month is range 1 .. 31;            
type Day_Of_Month_Access is access constant Day_Of_Month;

Anonymous access

An anonymous access is used as a parameter to a function, procedure or a discriminated type. Here some examples:

procedure Test (Some_Day : access Day_Of_Month);
task type Thread (
   Execute_For_Day : access Day_Of_Month)
is
   --  ...In Ada 2005 a
end Thread;
type Day_Data (
   Store_For_Day : access Day_Of_Month)
is record
   --  components
end record;

Before you use an anonymous access you should consider if the "out" or "in out" modifier is not more appropriate - see access performance to see why.


This language feature will be made available in the forthcoming Ada 2005 standard.

In Ada 2005 an anonymous access will also be allowed as part of a record:

type Object is record
   M    : Integer;
   Next : access Object;
end record;

Not null access

This language feature will be made available in the forthcoming Ada 2005 standard.

All access types can be modified with "not null":

type Day_Of_Month_Access is not null access Day_Of_Month;

The type must then always point to an object, so initializations are compulsory.

Constant anonymous access

This language feature will be made available in the forthcoming Ada 2005 standard.

An anonymous access to a constant object.

procedure Test (Some_Day : access constant Day_Of_Month);

Access to subprogram

An access to subprogram allows us to call a subprogram without knowing its name nor its declaration location. One of the uses of this kind of access is the well known callbacks.

type Callback_Procedure
is access procedure (
   Id   : Integer;
   Text : String);

type Callback_Function
is access function (
   The_Alarm : in  Alarm)
return
   Natural;

For getting an access to a subprogram the attribute Access is applied to a subprogram name with the proper prototype.

procedure Process_Event (
   Id   : Integer;
   Text : String);

My_Callback : Callback_Procedure := ProcessEvent'Access;

Anonymous access to subprogram

This language feature will be made available in the forthcoming Ada 2005 standard.

procedure Test (
   Call_Back : access procedure (
                         Id   : Integer;
                         Text : String));

Using access types

Creating object in a storage pool

Objects in a storage pool are created with the keyword new:

Father : Person_Ref := new Person'(Father_First_Name, Father_Last_Name);

Deleting object from a storage pool

Although the Ada standard mentioned the use of a garbage collector which would automatically remove all unneeded objects that had been created on the heap (storage pool), only Ada compilers targeting a virtual machine like Java or .NET actually have garbage collectors.

Therefore in order to delete an object from the heap you will need the generic unit Ada.Unchecked_Deallocation.

with Ada.Unchecked_Deallocation;

procedure Deallocation_Sample is

   type Vector is array (Integer range <>) of Float;
   type Vector_Ref is access Vector;
   procedure Free_Vector is new Ada.Unchecked_Deallocation
      (Object => Vector, Name => Vector_Ref);
  
   VA : Vector_Ref;

begin
   VA     := new Vector (1 .. 10);
   VA.all := (others => 0.0);
   --  ... Do whatever you need to do with the vector
   Free_Vector (VA); -- The memory is deallocated and VA is now null
end Deallocation_Sample;

Since Ada does allow for user defined storage pools you could also try a garbage collector library.

Implicit dereferencing

If you declare a record type, and an access type for it, thus:

  type Person is record
     First_Name : String (1..30);
     Last_Name  : String (1..20);
  end record;

  type Person_Access is access Person;

you can use these types as follows:

  Father : Person_Access := new Person'(Father_First_Name, Father_Last_Name);
  ...   
  Ada.Text_IO.Put(Father.all.First_Name);

However, .all is implicit if omitted, so we can write more concisely:

  Ada.Text_IO.Put(Father.First_Name);

and be careful:

  Obj1 : Person_Access := new Person'(...);
  Obj2 : Person_Access := new Person'(...);

  Obj1 := Obj2;          --  Obj1 now refers to the same person as Obj2 (shallow copy)
  Obj1.all := Obj2.all;  --  Obj1 still refers to a different object from Obj2, 
                         -- but it has the same content (deep copy).

Implicit dereferencing also applies to arrays:

  type Vector is array (0..3) of Complex;
  type Vector_Access is access Vector;

  VA : Vector_Access := new Vector;
  ...
  C : Complex := VA(3); -- a shorter equivalent for VA.all(3)

Access FAQ

A few "Frequently Asked Question" and "Frequently Encountered Problems" (mostly from former C users) regarding Ada's access types.

Access vs. access all

An access all can do anything a simple access can do. So one might ask: "Why use access at all?" - And indeed some programmers never use simple access.

But this is wrong because access all is more error prone! One example: When Unchecked_Deallocation is used on an access all it is not checked that the object actually belongs to the proper storage pool - or if the object belongs to any storage pool at all. The following example, invalidly and perhaps disastrously, will try to deallocate a stack object:

 declare
    type Day_Of_Month is range 1 .. 31;            
    type Day_Of_Month_Access is access all Day_Of_Month;

   procedure Free
   is new Ada.Unchecked_Deallocation (
       Object => Day_Of_Month
       Name   => Day_Of_Month_Access);

   A : aliased Day_Of_Month;
   Ptr : Day_Of_Month_Access := A'Access;
 begin
   Free(Ptr);
 end;

With a simple access you know at least that you won't try to deallocate a stack object.

Depending on the implementation an access might also render better performance then access all.

Access performance

Ada performs run-time checks on access types, so not all access types render the same performance. In other places of the Ada Programming we suggest that you should not care about runtime checks since the optimizer will remove them when they are not needed. However former C programmers often use anonymous access - which have worse performance - instead of of using "out" or "in out" which has best performance. Here a performance list - including the access modifiers - from best to worse:

  1. "in" modifier : parameter need only to be passed into the function.
  2. "out" modifier : parameter need only to be passed from the function.
  3. "in out" modifier : the compiler is free to use "call by value", "call by register" or "call by reference" and therefore best performance is to be expected.
  4. pool access : the access is always within a storage pool and only checks for not null are performed.
  5. access all : additional checks maybe needed.
  6. anonymous access : complex "stack deeps level" checks are needed so an "anonymous access" can be safely converted from and to an "access all" or "pool access".

Access vs. System.Address

An access is not a memory address. It is something more. For example, an "access to String" often needs some way of storing the string size as well. If you need a simple address and are not concerned about strong-typing, you may consider using the System.Address type.

C compatible pointer

The correct way to create a C compatible access is to use pragma Convention:

type Day_Of_Month is range 1 .. 31;

for Day_Of_Month'Size use Interfaces.C.int'Size;

pragma Convention (
   Convention => C,
   Entity     => Day_Of_Month);

type Day_Of_Month_Access is access Day_Of_Month;

pragma Convention (
   Convention => C,
   Entity     => Day_Of_Month_Access);

pragma Convention should be used on any type you want to use in C. The compiler should warn you if the type cannot be made C compatible.

You may also consider the following - shorter - alternative when declaring Day_Of_Month:

type Day_Of_Month is new Interfaces.C.int range 1 .. 31;

Before you use access types in C you should consider using the normal "in", "out" and "in out" modifiers. pragma Export and pragma Import knows how parameters are usually passed in C and will use a pointer to pass a parameter automatically where a "normal" C programmer would have used them as well.

Of course the definition of a "normal" C programmer is not left to change, the RM contains precise rules on when to use a pointer for "in", "out", and "in out" - see "B.3 Interfacing with C (http://www.adaic.com/standards/95lrm/html/RM-B-3.html) (Annotated (http://www.adaic.com/standards/95aarm/html/AA-B-3.html))".

Where is void*?

While actually been a problem for "interfacing with C", here is a possible solution:

procedure Test
is
  subtype Pvoid is System.Address;
  -- the declare in C, like this.
  -- int C_fun(int *)

  function C_fun(pv : Pvoid) return Integer;
  pragma Import (C,C_fun,"C_fun");

  Pointer : Pvoid ;

  Input_Parameter : Integer := 32;
  Return_Value    : Integer;
begin
  Pointer      := Input_Parameter'Address;
  Return_Value := C_fun(Pointer);
end Test;

Less portable but perhaps more usable (for 32 bit CPUs):

type void is mod 2 ** 32;
for void'Size use 32;

With GNAT you can get 32/64 bit portability by using:

type void is mod System.Memory_Size;
for void'Size use System.Word_Size;

See also

Wikibook

Ada Reference Manual

Ada 95

Ada 2005

  • 3.7 Discriminants (http://www.adaic.com/standards/rm-amend/html/RM-3-7.html) (Annotated (http://www.adaic.com/standards/rm-amend/html/AA-3-7.html))
  • 3.10 Access Types (http://www.adaic.com/standards/rm-amend/html/RM-3-10.html) (Annotated (http://www.adaic.com/standards/rm-amend/html/AA-3-10.html))
  • 6.1 Subprogram Declarations (http://www.adaic.com/standards/rm-amend/html/RM-6-1.html) (Annotated (http://www.adaic.com/standards/rm-amend/html/AA-6-1.html))
  • B.3 Interfacing with C (http://www.adaic.com/standards/rm-amend/html/RM-B-3.html) (Annotated (http://www.adaic.com/standards/rm-amend/html/AA-B-3.html))

Ada Quality and Style Guide


Also helps finding: AdaProgrammingMemory, AdaProgramming, ProgrammingMemory, sda, programing, memori, adu, programmin, memmory, adas, progamming, memor, adz, AdaProgrammingTypesaccess, ProgrammingTypes, Typesaccess

   
 
  
Add to bookmarks
Related Articles
 
Ada Programming
Computer programming
Top Articles
 
Ada Programming
Ada Programming/Keywords/constant
Ada Programming/Keywords/in
Ada Programming/Keywords/is
Ada Programming/Keywords/procedure
Ada Programming/Keywords/range
Ada Programming/Keywords/renames
Ada Programming/Keywords/use
Cookbook
Cookbook:Butter
Cookbook:Chicken
Cookbook:Egg
Cookbook:Flour
Cookbook:Ingredients
Cookbook:Tomato
Japanese
SA NCS:Consumer Studies
SA NCS:History
SA NCS:Mathematical Literacy
SA NCS:Qualification Assesment
Wikibooks Pokédex:Hoenn Index
Search LiveJournal blogs for Ada Programming/Memory
 

Free Car Repair Manuals  •  Credit Consolidation  •  Kamala  •  Find jobs •  Jobs search

Copyright @ 2005 eMyTextBooks.com
This article is from Wikibooks. All text is available under the terms of the GNU Free Documentation License.