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.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.67.3.225 with SMTP id bz1mr3837661pad.16.1407281150493; Tue, 05 Aug 2014 16:25:50 -0700 (PDT) X-Received: by 10.50.66.135 with SMTP id f7mr219014igt.3.1407281150183; Tue, 05 Aug 2014 16:25:50 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!h18no9284985igc.0!news-out.google.com!px9ni585igc.0!nntp.google.com!h18no9284982igc.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 5 Aug 2014 16:25:49 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=66.126.103.122; posting-account=KSa2aQoAAACOxnC0usBJYX8NE3x3a1Xq NNTP-Posting-Host: 66.126.103.122 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: A bad counterintuitive behaviour of Ada about OO From: Adam Beneschan Injection-Date: Tue, 05 Aug 2014 23:25:50 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:21473 Date: 2014-08-05T16:25:49-07:00 List-Id: On Tuesday, August 5, 2014 3:35:49 PM UTC-7, Victor Porton wrote: > So now I understand what I should do. To eliminate side effects when copy= ing=20 > subobjects of Base_Object type, I should remove overriding Adjust from=20 > Base_Object and define it manually for particular object types. Copy_Hand= le=20 > then becomes unnecessary and should be removed altogether. This seems to be on the right track. An "Adjust" procedure that destroys d= ata (e.g. by clearing it to 0, as you've done) is asking for trouble. The = problem, as you've found out, is that records could be copied at times when= you're not expecting. The semantics in the LRM for function calls and agg= regates talk about creating anonymous objects and then copying them to thei= r final destination, which could involve extra Adjust/Finalize calls. Then= it spells out cases where an implementation is permitted to build stuff in= place (instead of building in a temporary location and copying), and avoid= an Adjust/Finalize pair, and it spells out other cases where the implement= ation is *required* to build stuff in place. I tried your example with two different compilers, and in both cases, the p= rocess of calling Handled_Record.From_Handle led to an Adjust call that cle= ared the data to 0. This was true even after you added an explicit From_Ha= ndle for the Example_Object; your expression still called the Handled_Recor= d.From_Handle function and that led to the Adjust call. As an experiment, = I tried rewriting From_Handle from this: function From_Handle(Handle: Handle_Type) return Base_Object is=20 begin=20 return (Ada.Finalization.Controlled with Handle=3D>Handle);=20 end;=20 to this: function From_Handle(Handle: Handle_Type) return Base_Object is=20 begin=20 return Result : Base_Object do Result.Handle :=3D Handle; end return; end;=20 This caused the program to avoid calling Handled_Record.Adjust with one com= piler, thus outputting the expected result, but not with the other compiler= . And neither compiler is wrong. They're taking advantage of implementati= on permissions differently. So you have to be careful when defining Adjust/Finalize for a type. You ha= ve to make sure that whenever you call a function that returns that type, o= r use an aggregate or extension aggregate of that type, you have to make su= re the program will work if one *or* *more* Adjust/Finalize pairs are calle= d when moving the data around from one location to another, and you have to= make sure it will work if Adjust/Finalize are *not* called. Your original= Adjust fails that test. -- Adam