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.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ee887b7593f7961b X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!feeder.news-service.com!newsfeed.freenet.de!news.teledata-fn.de!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Ada OS based on Minix3 Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <1pmkcuemqczer.j2i34pvc2lne$.dlg@40tude.net> <81912719-8c66-439d-a40e-529b22acd8a6@u29g2000pro.googlegroups.com> <14t6hwu8udm8j$.1x339y69m2ew1.dlg@40tude.net> Date: Wed, 12 Nov 2008 10:47:37 +0100 Message-ID: <14ay3vz2ngj9s.1bmilwgckl3lc$.dlg@40tude.net> NNTP-Posting-Date: 12 Nov 2008 10:47:37 CET NNTP-Posting-Host: 00a0db04.newsspool3.arcor-online.net X-Trace: DXC=dSTneEmSmd@gj[ZPFj7ehOMcF=Q^Z^V3H4Fo<]lROoRA^YC2XCjHcbI_>;:69m`jGIDNcfSJ;bb[EFCTGGVUmh?DLK[5LiR>kgB:g1KS@=SLeD X-Complaints-To: usenet-abuse@arcor.de Xref: g2news2.google.com comp.lang.ada:8387 Date: 2008-11-12T10:47:37+01:00 List-Id: On Tue, 11 Nov 2008 17:09:54 -0500, Robert A Duff wrote: > "Dmitry A. Kazakov" writes: > >> On Mon, 10 Nov 2008 10:31:27 -0500, Robert A Duff wrote: >> >>> "Dmitry A. Kazakov" writes: >>> >>>> 6. Proper construction/destruction >>> >>> What do you see as the limitations/problems with Ada in this area? >> >> 1. User-defined initialization/finalization shall be definable for any >> type. I do mean any. > > Finalization: Agreed, but the compiler really needs to take care to > avoid distributed overhead. I don't see why it should be a distributed overhead. For example, access types are already initialized by null. The overhead, if any, is here, but it does not hurt. > Initialization: Use function calls. They work for all types. > I think we've discussed this idea before, but I don't remember > any fundamental problems. The fundamental problem is that a constructor cannot be decomposed into functions. In the function body you have to construct the object before you return it. Who does it and what? Under initialization I do not mean replacing a "default" value with something else. I mean creation a new object (at some memory location) initialized by a value. It had no other value before. Doing this by a function is semantically wrong. > The Initialize procedure of controlled > types seems unnecessary to me (although something needs to be done > regarding abort deferral). Right, because Initialize receives an already constructed object. It is too late to do many type-specific initializations, but too early to make the class-wide ones. >> 2. Composition rules of initialization/finalization for derived types must >> ensure execution of the user-defined initialization/finalization code for >> the base type. > > Agreed (except I think you mean "parent type", not "base type"). Well, I am unsure if there must be such distinction in the first place. But, OK, to begin with, let it be parent type. > This is a more general issue -- it would be useful to say > "must call parent op" for various things, including Finalize. Yes, it would be great to have "extensible" primitive operations. >> 3. User-defined initialization/finalization shall be definable for >> class-wide types. AKA dispatch from constructor/destructor. Actually, a >> part of the pos. 1. > > OK. There are some interesting issues here -- the constructor (a > function, in my mind) might want to plug a pointer-to-classwide into > some global data structure, but I want to make sure the specific-typed > thing is fully initialized and ready to be dispatched to, before that > happens. Right. >> 4. Task-as-a-component problem to be solved. > > Which problem is that? I mean the pattern: type Active is new Ada.Finalization.Limited_Controlled ...; private task Agent (Object : not null access Active'Class) ... type Active is new Ada.Finalization.Limited_Controlled with record Agent : Task (Active'Access); end record; It is broken, not even worth to try. Even in rare cases when the component task does not refer to its container type, the only way to make it working is to have a pointer to the task instead. In fact, any mix-in with an access to class-wide is extremely dangerous and error prone, *because* it is very difficult to initialize and finalize such things properly. But this is another story (about why we should have MI). >> 5. Getting a pool-specific pointer to the object upon >> initialization/finalization, when the object is allocated in such a pool. >> (Unchecked_Conversion is really nasty there) > > I think you mean Unchecked_Access -- Unchecked_Conversion is not > necessary. > > I don't see how this can make sense. In Initialize or Finalize, you > don't know whether the object is in a pool, nor which pool. So how can > you get a pool-specific pointer? That is exactly the problem. Consider objects allocated on a user-defined pool. The object are linked into some list. When a new object is created the "constructor" places it into the list. When the object is destroyed, the "destructor" removes it. For both, you need a self-pointer, but you cannot get it from an "in out" parameter. If access types had constructors/destructors, the programmer could place that stuff there, rather that trying to do it in the object. It does not belong there. > Also, given point 1 ("any type") the thing being init/finalized could be > a bitfield component of a packed record. Pointers to bitfields could > cause distributed overhead, if you're not careful. This is an issue how a constructor is chosen by the compiler. >> 6. LHS/RHS issue. > > What issue is that? I meant access to the left part of assignment. Provided that the assignment is to be generated out of the constructor and destructor. > How about: > > 7. It would be nice if Finalize would be passed a parameter indicating > the reason for finalization (normal exit, some exception occurrence, > abort). Perhaps also an ability to declare that finalization only > applies to certain "reasons". Yes, I always wished to have this for DB transaction objects. When the object is killed by an exception propagation it rolls the updates back. Otherwise it commits. > 8. Interactions with user-defined storage pools. > > 9. Interactions with garbage collection. I hope this can be solved on the basis of the constructor/destructor of the corresponding access type. Pool-specific named access types is one of the coolest things in Ada, IMO. > 10. Reify the finalization operation (that is, the operation on some > type that calls Finalize on all the parts of it, including the > whole). I.e. a destructor. But it is semantically broken to have such. It would destroy an object leaving a dangling typed name of. I think that the trick can be achieved with an access type to some fake storage pool. The Unchecked_Deallocation is called on the pointer. That does the finalization. Then the pool's Deallocate is called, which does nothing. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de