From mboxrd@z Thu Jan 1 00:00:00 1970 Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Unchecked_Deallocation with tagged class type. Date: Wed, 15 Nov 2023 22:17:37 +0100 Organization: A noiseless patient Spider Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Wed, 15 Nov 2023 21:17:35 -0000 (UTC) Injection-Info: dont-email.me; posting-host="2243a23eed6a547f86f030f62c3aa490"; logging-data="2010920"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/mgDPWYycxblO2TJBeb8rnnGO8cRWBTpU=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:5AKq9WdBYrTTKnQ03o6SG2S3YQA= Content-Language: en-US In-Reply-To: Xref: news.eternal-september.org comp.lang.ada:65848 List-Id: On 2023-11-15 21:26, Blady wrote: > Le 14/11/2023 à 23:42, Dmitry A. Kazakov a écrit : >>> But what does "Finalize (OB);"? >> >> Crashes your program. It is a bug. You should instantiate >> Unchecked_Deallocation with class-wide type if you pass a class-wide >> pointer. > > Thanks, I haven't considered this possibility. > Note: the previous program built with GNAT FSF 13.2.0 ran without > exception. > > I've changed: > with Ada.Unchecked_Deallocation; > procedure test_20231113_free_class is > >    type TTA is tagged record >       AA : Integer; >    end record; >    type ATTA is access all TTA; >    type CATTA is access all TTA'Class; >    procedure Finalize (O : in out CATTA) is >       procedure Free is new Ada.Unchecked_Deallocation (TTA'Class, CATTA); >    begin >       Free (O); >    end Finalize; > >    type TTB is new TTA with record >       BB : Integer; >    end record; >    type ATTB is access all TTB; >    type CATTB is access all TTB'Class; >    procedure Finalize (O : in out CATTB) is >    begin >       Finalize (CATTA (O)); >    end Finalize; > >    OA : CATTA := new TTA; >    OB : CATTB := new TTB; > > begin >    Finalize (OA); >    Finalize (OB); > end test_20231113_free_class; > > It runs without exception. > One question remains about "Finalize (OB);": > Which memory size is deallocated TTA'Size or TTB'Size? It is a wrong question. The implementation of the pool may ignore size using the block size instead. Furthermore T'Size is not necessarily the size actually allocated. Regarding Unchecked_Deallocation instantiated with a pointer to a class-wide object, consider it dispatching on the target object tag. Thus you can deallocate any object using any instance of Unchecked_Deallocation for any class-wide parent of, interfaces included. So Finalize (OB) is OK. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de