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 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Extending a third party tagged type while adding finalization Date: Mon, 4 Dec 2017 14:55:18 +0100 Organization: Aioe.org NNTP Server Message-ID: References: <4db43571-7f86-4e73-8849-c41160927703@googlegroups.com> <6496a10f-c97e-4e42-b295-2478ad464b2f@googlegroups.com> <6106dfe6-c614-4fc1-aace-74bf8d7435e3@googlegroups.com> <24767ee5-cda8-45e4-98d1-7da44757bd40@googlegroups.com> <037e7f02-9149-4648-b7c5-91f67c1c1961@googlegroups.com> <4ea6417a-d352-4af4-bfe5-241910bc9684@googlegroups.com> NNTP-Posting-Host: MyFhHs417jM9AgzRpXn7yg.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.8.2 Xref: reader02.eternal-september.org comp.lang.ada:49348 Date: 2017-12-04T14:55:18+01:00 List-Id: On 04/12/2017 14:19, AdaMagica wrote: > There is no Initialize defined for derived S. This is defined then implicitly as: > > procedure Initialize (X: in out S) is > begin > Initialize (T (X)); > end Initialize; > > This is the calling sequence: > Init S > Init T > Foo S Which is a wrong sequence per Ada design. Actually it is just Initialize of S This wrong sequence is fixed in practice by applying the pattern: procedure Initialize (X : in out Derived) is begin Parent (X).Initialize; -- Ensure parent's initialization end Initialize; Using the pattern you get a semantically correct sequence: -- enter Initialize of S -- enter Initialize of T -- leave Initialize of T -- leave Initialize of S But with Foo it becomes wrong again: + call Foo of S Which is catastrophic and there is *no* way to make it right in presence of multiple derived types. You cannot announce a call to a deferred implementation during initialization of a specific type T. That may happen only after initializations of all derived specific types are complete. Semantically it means that it must be called in the initialization of T'Class. The proper sequence must be: + call Foo of S -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de