B.3.2 The Generic Package Interfaces.C.Pointers
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.
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
The generic library 
package Interfaces.C.Pointers has the following declaration: 
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);
 
   type Pointer 
is access all Element;
 
   function Value(Ref        : 
in Pointer;
                  Terminator : 
in Element := Default_Terminator)
      
return Element_Array;
 
   function Value(Ref    : 
in Pointer;
                  Length : 
in ptrdiff_t)
      
return Element_Array;
 
   Pointer_Error : 
exception;
 
   -- C-style Pointer arithmetic
   function "+" (Left : in Pointer;   Right : in ptrdiff_t) return Pointer
      with Convention => Intrinsic;
   function "+" (Left : in ptrdiff_t; Right : in Pointer)   return Pointer
      with Convention => Intrinsic;
   function "-" (Left : in Pointer;   Right : in ptrdiff_t) return Pointer
      with Convention => Intrinsic;
   function "-" (Left : in Pointer;   Right : in Pointer) return ptrdiff_t
      with Convention => Intrinsic;
   procedure Increment (Ref : 
in out Pointer)
      
with Convention => Intrinsic;
   
procedure Decrement (Ref : 
in out Pointer)
      
with Convention => Intrinsic;
 
This paragraph 
was deleted.
   function Virtual_Length (Ref        : 
in Pointer;
                            Terminator : 
in Element := Default_Terminator)
      
return ptrdiff_t;
 
   procedure Copy_Terminated_Array
      (Source     : 
in Pointer;
       Target     : 
in Pointer;
       Limit      : 
in ptrdiff_t := ptrdiff_t'Last;
       Terminator : 
in Element :=  Default_Terminator);
 
   procedure Copy_Array (Source  : 
in Pointer;
                         Target  : 
in Pointer;
                         Length  : 
in ptrdiff_t);
 
end Interfaces.C.Pointers;
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: 
Explicit termination of an array value with Default_Terminator 
(a special terminator value);
Programmer-managed 
length, with Default_Terminator treated simply as a data element. 
function Value(Ref        : in Pointer;
               Terminator : in Element := Default_Terminator)
   return Element_Array;
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.
function Value(Ref    : in Pointer;
               Length : in ptrdiff_t)
   return Element_Array;
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. 
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. 
procedure Increment (Ref : in out Pointer);
Equivalent to Ref 
:= Ref+1.
procedure Decrement (Ref : in out Pointer);
Equivalent to Ref 
:= Ref–1.
function Virtual_Length (Ref        : in Pointer;
                         Terminator : in Element := Default_Terminator)
   return ptrdiff_t;
Returns the number 
of Elements, up to the one just before the first Terminator, in Value(Ref, 
Terminator).
procedure Copy_Terminated_Array
   (Source     : in Pointer;
    Target     : in Pointer;
    Limit      : in ptrdiff_t := ptrdiff_t'Last;
    Terminator : in Element := Default_Terminator);
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. 
procedure Copy_Array (Source  : in Pointer;
                      Target  : in Pointer;
                      Length  : in ptrdiff_t);
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
It is erroneous to dereference 
a Pointer that does not designate an aliased Element. 
 
Execution of Value(Ref, Terminator) 
is erroneous if Ref does not designate an aliased Element in an Element_Array 
terminated by Terminator.
 
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.
 
Execution of Virtual_Length(Ref, 
Terminator) is erroneous if Ref does not designate an aliased Element 
in an Element_Array terminated by Terminator.
 
Execution 
of Copy_Terminated_Array(Source, Target, Limit, Terminator) is erroneous 
in either of the following situations: 
 
Execution of both Value(Source, Terminator) and 
Value(Source, Limit) are erroneous, or
Copying writes past the end of the array containing 
the Element designated by Target. 
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. 
 
10  To compose 
a Pointer from an Element_Array, use 'Access on the first element. For 
example (assuming appropriate instantiations): 
Some_Array   : Element_Array(0..5) ;
Some_Pointer : Pointer := Some_Array(0)'Access;
Examples
Example of Interfaces.C.Pointers: 
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);
   use type Char_Ptrs.Pointer;
   subtype Char_Star is Char_Ptrs.Pointer;
   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;
      loop
         Element             := Source_Temp_Ptr.all;
         Target_Temp_Ptr.all := Element;
         exit when C."="(Element, C.nul);
         Char_Ptrs.Increment(Target_Temp_Ptr);
         Char_Ptrs.Increment(Source_Temp_Ptr);
      end loop;
   end Strcpy;
begin
   ...
end Test_Pointers;
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe