DocAda(tm) is a productivity tool of KSCE
|
|
|
|
About DocAda Light:
Preface / Preliminary
/ Help
/ TOC
/ Copyright
DocAda Online at the Ada Home:
Complete RM95
/ Updates
/ News
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; 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; procedure Increment (Ref : in out Pointer); procedure Decrement (Ref : in out Pointer); pragma Convention (Intrinsic, "+"); pragma Convention (Intrinsic, "-"); pragma Convention (Intrinsic, Increment); pragma Convention (Intrinsic, Decrement); 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:
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;
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);
procedure Decrement (Ref : in out Pointer);
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);
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 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.
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 Element = C.nul; Char_Ptrs.Increment(Target_Temp_Ptr); Char_Ptrs.Increment(Source_Temp_Ptr); end loop; end Strcpy; begin ... end Test_Pointers;
About DocAda Light:
Preface / Preliminary
/ Help
/ TOC
/ Copyright
DocAda Online at the Ada Home:
Complete RM95
/ Updates
/ News
|
|
|
|