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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,be30d7bb9651853b X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-12-11 10:59:41 PST Newsgroups: comp.lang.ada Path: bga.com!news.sprintlink.net!howland.reston.ans.net!news.moneng.mei.com!uwm.edu!lll-winken.llnl.gov!noc.near.net!inmet!dsd!bobduff From: bobduff@dsd.camb.inmet.com (Bob Duff) Subject: Re: Ada 90 inheritance request? Message-ID: Sender: news@inmet.camb.inmet.com Organization: Intermetrics, Inc. References: <3ca3vl$n14@lang8.cs.nyu.edu> Date: Sun, 11 Dec 1994 18:47:16 GMT Date: 1994-12-11T18:47:16+00:00 List-Id: In article <3ca3vl$n14@lang8.cs.nyu.edu>, Cyrille Comar wrote: >PROBLEM: I have defined a hierarchy or tagged types and now I would like > specialize one of them to be controlled (i.e. finalizable) This issue came up in the review process, and I'll repeat pretty much what we said at the time. I think you have to ask what are the Initialize and Finalize *doing*? In most cases, you want to add controlledness because you are adding a component that needs it. For example, you are extending the parent type by adding a component of an access type, and you want finalization to clean up the heap object. In this (most common) case, it's no big deal -- just make the new component be of a controlled type. Whenever an object of the derived type is finalized, all of its components will be finalized. In this case, Initialize and Finalize don't need access to the containing object. It's hard to imagine a case where Initialize and Finalize for the new component(s) *do* need access to the containing object. Can anybody think of a realistic one? I would be interested to hear it. I suppose if the parent type needs finalization, but doesn't have it, then one might want to add it to avoid storage leaks or whatever. But in that case, the parent type is already broken. Type extension is mainly for extending abstractions, not really for fixing broken ones -- the latter is what Emacs is for. ;-) If the Initialize and Finalize *do* need access to the parent's fields, then the access-discriminant method can be used. But, as you point out, it only works for limited types. By the way, in your example: > type Acc is access all Ctrl_T; > type T_Controller (Englobing_Obj : Acc) is new Limited_Controlled > with null record; > > type Ctrl_T is new T with record > Ctrl : T_Controller (Ctrl_T'Access); > end; Englobing_Obj is *not* an access discriminant. It is a discriminant, and it is of a *named* access type. An "access discriminant" is a discriminant of an *anonymous* access type. (The terminology is a bit confusing, I admit.) As you wrote it, the example would be illegal, because it violates the accessibility rules (i.e. it can create dangling references). You could make it legal by changing 'Access to 'Unchecked_Access, but that leaves the possibility of dangling references (somebody might copy the value of the discriminant into a global variable of type Acc). Better to use an access discriminant: type T_Controller(Englobing_Obj: access Ctrl_T) is ... This prevents dangling references, and is legal. By the way, the "limited" rule you referred to is that only a limited type can have an access discriminant. Any type (limited or nonlimited) can have a discriminant of a named access type. (Well, it has to be composite, and not an array.) - Bob -- Bob Duff bobduff@inmet.com Oak Tree Software, Inc. Ada 9X Mapping/Revision Team (Intermetrics, Inc.)