Go to the first, previous, next, last section, table of contents.


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:
    1. Explicit termination of an array value with Default_Terminator (a special terminator value);
    2. Programmer-managed length, with Default_Terminator treated simply as a data element.

  1. function Value(Ref        : in Pointer;
                   Terminator : in Element := Default_Terminator)
      return Element_Array;
    
    1. This function returns an Element_Array whose value is the array pointed to by Ref, up to and including the first Terminator; the lower bound of the array is Index'First. Interfaces.C.Strings.Dereference_Error is propagated if Ref is null.

  1. function Value(Ref    : in Pointer;
                   Length : in ptrdiff_t)
       return Element_Array;
    
    1. This function returns an Element_Array comprising the first Length elements pointed to by Ref. The exception Interfaces.C.Strings.Dereference_Error is propagated if Ref is null.

  1. 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.
  2. procedure Increment (Ref : in out Pointer);
    
    1. Equivalent to Ref := Ref+1.

  1. procedure Decrement (Ref : in out Pointer);
    
    1. Equivalent to Ref := Ref-1.

  1. function Virtual_Length
      (Ref        : in Pointer;
       Terminator : in Element := Default_Terminator)
       return ptrdiff_t;
    
    1. Returns the number of Elements, up to the one just before the first Terminator, in Value(Ref, Terminator).

  1. procedure Copy_Terminated_Array
      (Source     : in Pointer;
       Target     : in Pointer;
       Limit      : in ptrdiff_t := ptrdiff_t'Last;
       Terminator : in Element := Default_Terminator);
    
    1. This procedure copies Value(Source, Terminator) into the array pointed to by Target; it stops either after Terminator has been copied, or the number of elements copied is Limit, whichever occurs first. Dereference_Error is propagated if either Source or Target is null.

  1. procedure Copy_Array (Source  : in Pointer;
                          Target  : in Pointer;
                          Length  : in ptrdiff_t);
    
    1. This procedure copies the first Length elements from the array pointed to by Source, into the array pointed to by Target. Dereference_Error is propagated if either Source or Target is null.

Erroneous Execution

  1. It is erroneous to dereference a Pointer that does not designate an aliased Element.
  2. Execution of Value(Ref, Terminator) is erroneous if Ref does not designate an aliased Element in an Element_Array terminated by Terminator.
  3. 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.
  4. Execution of Virtual_Length(Ref, Terminator) is erroneous if Ref does not designate an aliased Element in an Element_Array terminated by Terminator.
  5. Execution of Copy_Terminated_Array(Source, Target, Limit, Terminator) is erroneous in either of the following situations:
    1. Execution of both Value(Source,Terminator) and Value(Source,Limit) are erroneous, or
    2. Copying writes past the end of the array containing the Element designated by Target.

  1. 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.

    NOTES

  2. (14) To compose a Pointer from an Element_Array, use 'Access on the first element. For example (assuming appropriate instantiations):
  3. Some_Array   : Element_Array(0..5) ;
    Some_Pointer : Pointer := Some_Array(0)'Access;
    

    Examples

  4. Example of Interfaces.C.Pointers:
  5. 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);
    
  6.    use type Char_Ptrs.Pointer;
       subtype Char_Star is Char_Ptrs.Pointer;
    
  7.    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;
    
  8.       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;
    


Go to the first, previous, next, last section, table of contents.