Prev | Up | ____ | Back | Forward
TOC -- / --.-- / --.--.-- | Index | Search | Syntax | Help


B.3.2 The Generic Package Interfaces.C.Pointers

(1)
The generic package Interfaces.C.Pointers allows the Ada programmer to perform C-style operations on pointers. It includes an access type Pointer, Value functions that dereference a Pointer and deliver the designated array, several pointer arithmetic operations, and ``copy'' procedures that copy the contents of a source pointer into the array designated by a destination pointer. As in C, it treats an object Ptr of type Pointer as a pointer to the first element of an array, so that for example, adding 1 to Ptr yields a pointer to the second element of the array.
(2)
The generic allows two styles of usage: one in which the array is terminated by a special terminator element; and another in which the programmer needs to keep track of the length.
Static Semantics
(3)
The generic library package Interfaces.C.Pointers has the following declaration:
(4)
       generic
          type Index is (<>);
          type Element is private;
          type Element_Array is array (Index range <>) of aliased Element;
          Default_Terminator : Element;
       package Interfaces.C.Pointers is
          pragma Preelaborate(Pointers);
(5)
          type Pointer is access all Element;
(6)
          function Value(Ref        : in Pointer;
                         Terminator : in Element := Default_Terminator)
             return Element_Array;
(7)
          function Value(Ref    : in Pointer;
                         Length : in ptrdiff_t)
             return Element_Array;
(8)
          Pointer_Error : exception;
(9)
          -- C-style Pointer arithmetic
(10)
          function "+" (Left : in Pointer;   Right : in ptrdiff_t) return Pointer;
          function "+" (Left : in ptrdiff_t; Right : in Pointer)   return Pointer;
          function "-" (Left : in Pointer;   Right : in ptrdiff_t) return Pointer;
          function "-" (Left : in Pointer;   Right : in Pointer)   return ptrdiff_t;
(11)
          procedure Increment (Ref : in out Pointer);
          procedure Decrement (Ref : in out Pointer);
(12)
          pragma Convention (Intrinsic, "+");
          pragma Convention (Intrinsic, "-");
          pragma Convention (Intrinsic, Increment);
          pragma Convention (Intrinsic, Decrement);
(13)
          function Virtual_Length (Ref        : in Pointer;
                                   Terminator : in Element := Default_Terminator)
             return ptrdiff_t;
(14)
          procedure Copy_Terminated_Array (Source     : in Pointer;
                                           Target     : in Pointer;
                                           Limit      : in ptrdiff_t := ptrdiff_t'Last;
                                           Terminator : in Element :=  Default_Terminator);
(15)
          procedure Copy_Array (Source  : in Pointer;
                                Target  : in Pointer;
                                Length  : in ptrdiff_t);
(16)
       end Interfaces.C.Pointers;
(17)
The type Pointer is C-compatible and corresponds to one use of C's ``Element *''. An object of type Pointer is interpreted as a pointer to the initial Element in an Element_Array. Two styles are supported:
(18)
(19)
(20)
       function Value(Ref        : in Pointer;
                      Terminator : in Element := Default_Terminator)
          return Element_Array;
(21)
(22)
       function Value(Ref    : in Pointer;
                      Length : in ptrdiff_t)
          return Element_Array;
(23)
(24)
The "+" and "-" functions perform arithmetic on Pointer values, based on the Size of the array elements. In each of these functions, Pointer_Error is propagated if a Pointer parameter is null.
(25)
       procedure Increment (Ref : in out Pointer);
(26)
(27)
       procedure Decrement (Ref : in out Pointer);
(28)
(29)
       function Virtual_Length (Ref        : in Pointer;
                                Terminator : in Element := Default_Terminator)
          return ptrdiff_t;
(30)
(31)
       procedure Copy_Terminated_Array (Source     : in Pointer;
                                        Target     : in Pointer;
                                        Limit      : in ptrdiff_t := ptrdiff_t'Last;
                                        Terminator : in Element := Default_Terminator);
(32)
(33)
       procedure Copy_Array (Source  : in Pointer;
                             Target  : in Pointer;
                             Length  : in ptrdiff_t);
(34)
Erroneous Execution
(35)
It is erroneous to dereference a Pointer that does not designate an aliased Element.
(36)
Execution of Value(Ref, Terminator) is erroneous if Ref does not designate an aliased Element in an Element_Array terminated by Terminator.
(37)
Execution of Value(Ref, Length) is erroneous if Ref does not designate an aliased Element in an Element_Array containing at least Length Elements between the designated Element and the end of the array, inclusive.
(38)
Execution of Virtual_Length(Ref, Terminator) is erroneous if Ref does not designate an aliased Element in an Element_Array terminated by Terminator.
(39)
Execution of Copy_Terminated_Array(Source, Target, Limit, Terminator) is erroneous in either of the following situations:
(40)
(41)
(42)
Execution of Copy_Array(Source, Target, Length) is erroneous if either Value(Source, Length) is erroneous, or copying writes past the end of the array containing the Element designated by Target.

(43)
(44)
          Some_Array   : Element_Array(0..5) ;
          Some_Pointer : Pointer := Some_Array(0)'Access;
Examples
(45)
Example of Interfaces.C.Pointers:
(46)
       with Interfaces.C.Pointers;
       with Interfaces.C.Strings;
       procedure Test_Pointers is
          package C renames Interfaces.C;
          package Char_Ptrs is
             new C.Pointers (Index              => C.size_t,
                             Element            => C.char,
                             Element_Array      => C.char_array,
                             Default_Terminator => C.nul);
(47)
          use type Char_Ptrs.Pointer;
          subtype Char_Star is Char_Ptrs.Pointer;
(48)
          procedure Strcpy (Target_Ptr, Source_Ptr : Char_Star) is
             Target_Temp_Ptr : Char_Star := Target_Ptr;
             Source_Temp_Ptr : Char_Star := Source_Ptr;
             Element : C.char;
          begin
             if Target_Temp_Ptr = null or Source_Temp_Ptr = null then
                raise C.Strings.Dereference_Error;
             end if;
(49)
             loop
                Element             := Source_Temp_Ptr.all;
                Target_Temp_Ptr.all := Element;
                exit when Element = C.nul;
                Char_Ptrs.Increment(Target_Temp_Ptr);
                Char_Ptrs.Increment(Source_Temp_Ptr);
             end loop;
          end Strcpy;
       begin
          ...
       end Test_Pointers;

Prev | Up | ____ | Back | Forward
TOC -- / --.-- / --.--.-- | Index | Search | Syntax | Help

Ada WWW Home -- Email comments, additions, corrections, gripes, kudos, etc. to:

Magnus Kempe -- Magnus.Kempe@di.epfl.ch
Copyright statement
Page last generated: 95-03-12