Why doesn�t the Ada95 language support general access-to-constant parameters? General access parameters are a very useful construct of the Ada95 language. Their use and advantages are discussed in several sections of the Rationale. I have also seen the construct abused in several bindings to C software; a general access parameter - an access-to-object parameter - is used where an access-to-constant parameter should have been used. An example of what I consider general access parameter abuse follows. Brian G. Holmes GTE Government Systems Corporation brian.holmes@gsc.gte.com ----------------------------------------------------------------------------------------------------------------------- -- -- General_Access_Parameter_Abuse_Example... -- -- Illustrates the abuse of general access parameters when creating bindings. -- -- The example is meant to show how parameters that might better accept access-to-constant values are coded to accept -- access-to-variable values. The result is that the user must convert constant objects into variable objects before -- using the interface. The example is somewhat contrived, but it is easy to see how it might be extended to a more -- complex and less familiar function. -- -- The memory.h and string.h files both declare the memcpy function as "void *memcpy(void *, const void *, size_t);". -- -- 19970923 BGH; created. -- ----------------------------------------------------------------------------------------------------------------------- with Ada.Text_IO; with Interfaces.C; procedure General_Access_Parameter_Abuse_Example is type Identification_Information is tagged record Number : Interfaces.C.int; Text : Interfaces.C.char_array(0..80); end record; Bits_Per_Byte : constant := 8; Identification_Information_Byte_Size : constant Interfaces.C.size_t := Interfaces.C.size_t(Identification_Information'size/Bits_Per_Byte); -- procedure Bad_Interface( Name: in out Identification_Information; Given: in Identification_Information ) is procedure Memcpy( Target: access Identification_Information; Source: access Identification_Information; Length: in Interfaces.C.size_t ); pragma Import( C,Memcpy,"memcpy" ); Local_Copy_Of_Given: aliased Identification_Information := Given; begin Memcpy( Name'access,Local_Copy_Of_Given'access,Identification_Information_Byte_Size ); end Bad_Interface; -- procedure Good_Interface( Name: in out Identification_Information; Given: in Identification_Information ) is type Constant_Char_Array_Access is access constant Identification_Information; procedure Memcpy( Target: access Identification_Information; Source: in Constant_Char_Array_Access; Length: in Interfaces.C.size_t ); pragma Import( C,Memcpy,"memcpy" ); begin Memcpy( Name'access,Given'access,Identification_Information_Byte_Size ); end Good_Interface; -- Constant_Identifier : constant Identification_Information := (332211,(0..1=>'0',others=>Interfaces.C.nul)); Identifier : Identification_Information; begin Ada.Text_IO.Put_Line( "*" ); Ada.Text_IO.Put_Line( "* General_Access_Parameter_Abuse_Example..." ); Ada.Text_IO.Put_Line( "* =========================================" ); Ada.Text_IO.Put_Line( "* Constant_Identifier is (" & Interfaces.C.int'image(Constant_Identifier.Number) & ",""" & Interfaces.C.To_Ada(Constant_Identifier.Text) & """ )." ); Bad_Interface( Identifier,Constant_Identifier ); Ada.Text_IO.Put_Line( "* Identifier is (" & Interfaces.C.int'image(Identifier.Number) & ",""" & Interfaces.C.To_Ada(Identifier.Text) & """ )." ); Good_Interface( Identifier,Constant_Identifier ); Ada.Text_IO.Put_Line( "* Identifier is (" & Interfaces.C.int'image(Identifier.Number) & ",""" & Interfaces.C.To_Ada(Identifier.Text) & """ )." ); Ada.Text_IO.Put_Line( "* =========================================" ); Ada.Text_IO.Put_Line( "*" ); end General_Access_Parameter_Abuse_Example; -----------------------------------------------------------------------------------------------------------------------