Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
 
Annotated Ada Reference Manual (Ada 2022 Draft 35)Legal Information
Contents   Index   References   Search   Previous   Next 

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/5
{AI12-0445-1} 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 keeps needs to keep track of the length. 

Static Semantics

3
The generic library package Interfaces.C.Pointers has the following declaration: 
4/5
{AI12-0241-1} {AI12-0302-1} 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
   with pragma Preelaborate, Nonblocking, Global => in out synchronized is(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/3
{AI05-0229-1}    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;
11/3
{AI05-0229-1}    procedure Increment (Ref : in out Pointer)
      with Convention => Intrinsic;
   procedure Decrement (Ref : in out Pointer)
      with Convention => Intrinsic;
12/3
This paragraph was deleted.{AI05-0229-1}
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
Explicit termination of an array value with Default_Terminator (a special terminator value);
19
Programmer-managed length, with Default_Terminator treated simply as a data element. 
20
function Value(Ref        : in Pointer;
               Terminator : in Element := Default_Terminator)
   return Element_Array;
21
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.
22
function Value(Ref    : in Pointer;
               Length : in ptrdiff_t)
   return Element_Array;
23
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
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
Equivalent to Ref := Ref+1.
27
procedure Decrement (Ref : in out Pointer);
28
Equivalent to Ref := Ref–1.
29
function Virtual_Length (Ref        : in Pointer;
                         Terminator : in Element := Default_Terminator)
   return ptrdiff_t;
30
Returns the number of Elements, up to the one just before the first Terminator, in Value(Ref, Terminator).
31
procedure Copy_Terminated_Array
   (Source     : in Pointer;
    Target     : in Pointer;
    Limit      : in ptrdiff_t := ptrdiff_t'Last;
    Terminator : in Element := Default_Terminator);
32
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
32.a
Ramification: It is the programmer's responsibility to ensure that elements are not copied beyond the logical length of the target array. 
32.b
Implementation Note: The implementation has to take care to check the Limit first. 
33
procedure Copy_Array (Source  : in Pointer;
                      Target  : in Pointer;
                      Length  : in ptrdiff_t);
34
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

35
It is erroneous to dereference a Pointer that does not designate an aliased Element. 
35.a
Discussion: Such a Pointer could arise via "+", "–", Increment, or Decrement.
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
Execution of both Value(Source, Terminator) and Value(Source, Limit) are erroneous, or
41
Copying writes past the end of the array containing the Element designated by Target. 
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
NOTE   To compose a Pointer from an Element_Array, use 'Access on the first element. For example (assuming appropriate instantiations): 
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/1
{8652/0065} {AI95-00142-01}       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;

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe