From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c81abf4ad443b68e X-Google-Attributes: gid103376,public From: Matthew Heaney Subject: Re: generic package System.Address_To_Access_Conversion Date: 1998/11/24 Message-ID: #1/1 X-Deja-AN: 415099247 Sender: matt@mheaney.ni.net References: <3659CDAE.AFE2EC5B@wec.com> NNTP-Posting-Date: Tue, 24 Nov 1998 00:33:29 PDT Newsgroups: comp.lang.ada Date: 1998-11-24T00:00:00+00:00 List-Id: R Heltzel writes: > Could someone please send me an example piece of code that illustrates > the method of using this generic package using the GNAT compiler? I've been using this to turn a read-only view of an object into a read-write view. For example, if you have an access-to-constant type: type Stack_Access is access constant Stack_Type; then modifying the stack designated by such an access object is illegal. But, you can get around this feature by using Addr_To_Acc_Conv: procedure Op (S : in Stack_Access) is package Conversions is new System.Address_To_Access_Conversions (Stack_Type); use Conversions; Read_Only_Stack : Stack_Type renames S.all; Read_Write_Stack : Stack_Type renames To_Pointer (Read_Only_Stack'Address).all; begin Push (19, On => Read_Write_Stack); end Op; Of course, if you're using gnat, then you can use the attribute T'Unrestricted_Access, which is more type-safe but less portable: procedure Op (S : in Stack_Access) is type Read_Write_Stack_Access is access all Stack_Type; for Read_Write_Stack_Access'Storage_Size use 0; SA : constant Read_Write_Stack_Access := S.all'Unrestricted_Access; Read_Write_Stack : Stack_Type renames SA.all; begin Push (19, On => Read_Write_Stack); end Op; Perhaps more clear is to just make the parameter mode "in Stack_Type" (this is how you can implement an operation that has side effect, even for a function). First, let's use our little friend Sys.Addr_To_Acc_Conv: procedure Op (S : in Stack_Type) is package Conversions is new System.Address_To_Access_Conversions (Stack_Type); use Conversions; Read_Write_Stack : Stack_Type renames To_Pointer (S'Address).all; begin Push (19, On => Read_Write_Stack); end Op; (Note the mode of param S.) Now, using T'Unrestricted_Access: procedure Op (S : in Stack_Type) is type Read_Write_Stack_Access is access all Stack_Type; for Read_Write_Stack_Access'Storage_Size use 0; SA : constant Read_Write_Stack_Access := S'Unrestricted_Access; Read_Write_Stack : Stack_Type renames SA.all; begin Push (19, On => Read_Write_Stack); end Op; Where possible, it's nice to take T'Address of an object whose type is pass-by-reference. That is, a tagged type, or a limited type whose full-view is also limited. The implementation advice in the RM recommends that taking T'Address of a by-reference type should return "a useful result," which will improve your chances for portability.