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.107.149.10 with SMTP id x10mr2991839iod.25.1498576780431; Tue, 27 Jun 2017 08:19:40 -0700 (PDT) X-Received: by 10.36.46.202 with SMTP id i193mr39959ita.8.1498576780403; Tue, 27 Jun 2017 08:19:40 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!x12no221914itb.0!news-out.google.com!k7ni1436itk.0!nntp.google.com!185no1694587itv.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 27 Jun 2017 08:19:40 -0700 (PDT) In-Reply-To: <71c4fdcd-4213-4b84-b852-c8674cfaf717@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=2003:c7:83c0:d4c0:822:4336:fdd0:2a37; posting-account=rmHyLAoAAADSQmMWJF0a_815Fdd96RDf NNTP-Posting-Host: 2003:c7:83c0:d4c0:822:4336:fdd0:2a37 References: <1ac5a44b-4423-443a-a7bb-2864d9abe78f@googlegroups.com> <1498048151.20885.28.camel@obry.net> <96174ea5-852d-44e9-8535-7c1eb24d5326@googlegroups.com> <8d3aff06-82df-485f-89e5-a50c326aab05@googlegroups.com> <66aa262e-2ac9-4016-b32d-e9fee14779e1@googlegroups.com> <88e2f18a-0786-4303-a5b8-fe82e8c81dcb@googlegroups.com> <71c4fdcd-4213-4b84-b852-c8674cfaf717@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <0f43638d-8954-4db2-94a3-b6615754da34@googlegroups.com> Subject: Re: Ada Annoyances From: AdaMagica Injection-Date: Tue, 27 Jun 2017 15:19:40 +0000 Content-Type: text/plain; charset="UTF-8" Xref: news.eternal-september.org comp.lang.ada:47146 Date: 2017-06-27T08:19:40-07:00 List-Id: Am Montag, 26. Juni 2017 22:35:34 UTC+2 schrieb Maciej Sobczak: > The complete example (analogous to the C++ example I have written in the other post) is: > > with Ada.Text_IO; > with Ada.Finalization; > > procedure Test is > > package P is > type Base is new Ada.Finalization.Limited_Controlled with null record; > > procedure Initialize (Obj : in out Base); > procedure VFoo (Obj : in Base); > > type Derived is new Base with null record; > > procedure Initialize (Obj : in out Derived); > procedure VFoo (Obj : in Derived); > > procedure Use_Object (Obj : in Base'Class); > end P; > ... > > When executed, we get: > > test with Base > call from Base's Initialize > Hello from Base > test with Derived > call from Base's Initialize > Hello from Derived <<<<<<< here are dragons! > call from Derived's Initialize > Hello from Derived Yes, this *is* a problem. The reason are the initialize *procedures* and the view conversion. The following uses *functions* instead (which behave more like C++'s constructors). This program works correctly just like the C++ version. (It seems that there is a bug in Gnat here. See comments in the code.) package Maciej is type Base is tagged record I: Integer; -- Gnat bug? Need this lest call of Base'(Create) will be optimized away end record; function Create return Base; procedure Foo (X: Base); type Derived is new Base with null record; function Create return Derived; procedure Foo (X: Derived); procedure Use_Object (X: Base'Class); end Maciej; ----------- with Ada.Text_IO; package body Maciej is -- Ada hasn't constructors comparable with those of C++. function Create return Base is B: Base := (I => 19); -- Here, the C++ constructor would be called. begin Ada.Text_IO.Put_Line (" Calling Use_Object from Base constructor:"); Use_Object (B); return B; end Create; procedure Foo (X: Base) is begin Ada.Text_IO.Put_Line (" Hello from Base object!"); end Foo; function Create return Derived is D: Derived := (Base'(Create) with null record); begin Ada.Text_IO.Put_Line (" Calling Use_Object from Derived constructor:"); Use_Object (D); return D; end Create; procedure Foo (X: Derived) is begin Ada.Text_IO.Put_Line (" Hello from Derived object!"); end Foo; procedure Use_Object (X: Base'Class) is begin X.Foo; end Use_Object; end Maciej; ----------- with Ada.Text_IO; with Maciej; procedure Maciej_Main is begin Ada.Text_IO.Put_Line ("Test with Base object:"); declare B: Maciej.Base := Maciej.Create; begin null; end; Ada.Text_IO.New_Line; Ada.Text_IO.Put_Line ("Test with Derived object:"); declare D: Maciej.Derived := Maciej.Create; begin null; end; Ada.Text_IO.New_Line; Ada.Text_IO.Put_Line ("Same again with procedures:"); declare B: Maciej.Base; begin B.Create; end; declare D: Maciej.Derived; begin D.Create; end; end Maciej_Main; Test with Base object: Calling Use_Object from Base constructor: Hello from Base object! Test with Derived object: Calling Use_Object from Base constructor: Hello from Base object! Calling Use_Object from Derived constructor: Hello from Derived object!