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=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,147f221051e5a63d X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!newsfeed2.dallas1.level3.net!news.level3.com!newsfeed-00.mathworks.com!nntp.TheWorld.com!not-for-mail From: Robert A Duff Newsgroups: comp.lang.ada Subject: Re: memory management in Ada: tedious without GC? Date: Sat, 24 May 2008 12:14:56 -0400 Organization: The World Public Access UNIX, Brookline, MA Message-ID: References: <4ddef8bf-b5b1-4d7e-b75b-386cd6c8402c@l17g2000pri.googlegroups.com> <9f2c2db4-d6c1-4cdf-884c-5cbc26ac7701@d1g2000hsg.googlegroups.com> <1qxcw3pphdlek.1jgsfwb7atdmo.dlg@40tude.net> <10j4zhb9ge8ea.156spz1dkc4vb$.dlg@40tude.net> NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: pcls6.std.com 1211645696 3284 192.74.137.71 (24 May 2008 16:14:56 GMT) X-Complaints-To: abuse@TheWorld.com NNTP-Posting-Date: Sat, 24 May 2008 16:14:56 +0000 (UTC) User-Agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.3 (irix) Cancel-Lock: sha1:yhoOKOFu5V3y1JUzl3EGXrqPEc8= Xref: g2news1.google.com comp.lang.ada:328 Date: 2008-05-24T12:14:56-04:00 List-Id: "Dmitry A. Kazakov" writes: > On Fri, 23 May 2008 19:15:45 -0400, Robert A Duff wrote: > >> "Dmitry A. Kazakov" writes: >> >>> 1. You don't know exactly the order in which the Finalize of the controlled >>> component gets called. So if you access the container object over an >>> access discriminant, that might be already invalid. >> >> You know something about the order. Initialize is bottom-up, >> Finalize is top-down. And when there are access discrims, the >> order among subling-components is specified by the RM. >> >> I would prefer a fully defined order, based on the declaration order. > > Hmm, that would be even more broken, I think. The language should not > require more than necessary to implement the programmer's intent. How does the compiler know the programmer's intent? Maybe order is important, maybe not. >...The order > of record components or discriminants has no semantic meaning (except when > representation clauses involved). It sometimes has meaning -- that's why we have positional-notation record aggregates. > The compiler should be able to re-order and even remove them,... You mean lay them out in memory? Sure, the compiler should choose an efficient layout, which is not necessarily the same as the declaration order. That's OK, because record layout is invisible, except when you're doing low-level stuff (e.g. interfacing to something outside the Ada world). >... as well as > initialization of. There, I disagree. I see zero advantage to allowing arbitrary order for the calls to Initialize and Finalize. And one huge disadvantage -- if you depend on the order, either on purpose or by accident, you might get a bug introduced years later, when you switch compilers (or even compiler versions). It will be very hard to detect and to fix that bug! Consider two finalization actions -- one flushes a buffer to disk, and the other closes the file handle. >... Consider a statically constrained discriminant as an > example. If the compiler could remove it, we would have the problem of > measurement units solved! Yes. I've always wanted to do that optimization. The strange thing is that most compilers do exactly that for array bounds, but not for discriminants. Array bounds are really discriminants, deep down! ;-) >>> 4. The pattern is exposed to multiple inheritance diamond diagram problem, >>> when such components are added independently. >> >> I don't understand your point here. Could you give an example of the >> problem? > > type A is limited tagged record ...; > type B is new A with record > -- a controlled component here to handle finalization of A > > generic > type Some_A is new A with private; > package P is > type C is new Some_A with record > -- a controlled component here to handle finalization of A > > Now, if P is instantiated with B, finalization of A will be handled twice. > > The problem is that finalization in C++ terms is a "virtual" member, while > record components are "non-virtual". Implementation of one through another > is IMO fundamentally broken. OK, I understand the above example (although I don't see a diamond). My answer is, "So don't do that". ;-) Why would you put the finalization for A in B? Put it in A where it belongs. The main reason to add finalization to B is if B adds new components that need to be cleaned up. If so, then wrap those components in a controlled type. - Bob