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: a07f3367d7,65b902127ca8a604 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news1.google.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post02.iad.highwinds-media.com!news.flashnewsgroups.com-b7.4zTQh5tI3A!not-for-mail Newsgroups: comp.lang.ada Subject: Re: Issue with GNAT GPL 2009 and GtkAda References: <4A414EBB.8060204@free.fr> <1avd65rn49abv$.krcxo2gdzb16$.dlg@40tude.net> <4a43c9ce$0$420$426a74cc@news.free.fr> <4a44ae4e$0$6295$4f793bc4@news.tdc.fi> From: Stephen Leake Date: Sat, 27 Jun 2009 07:11:46 -0400 Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (windows-nt) Cancel-Lock: sha1:hHng2cpWLE4YswwIi2YAmeT0FWQ= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Complaints-To: abuse@flashnewsgroups.com Organization: FlashNewsgroups.com X-Trace: 678454a45fe77e9cadf9d15879 Xref: g2news2.google.com comp.lang.ada:6661 Date: 2009-06-27T07:11:46-04:00 List-Id: "Randy Brukardt" writes: >>Niklas Holsti" wrote in message >>news:4a44ae4e$0$6295$4f793bc4@news.tdc.fi... >> > Damien Carbonne writes: >> >> >> >> type Listener is interface; >> >> procedure Process (L : in out Listener) is abstract; >> ... >> >> type Base is tagged null record; >> ... >> >> type Derived is new Base and Listener with null record; >> >> overriding procedure Process (D : in out Derived); >> >> >> >> Stephen Leake wrote: >>> The problem is clear here. >>> >>> "D : in out Derived" is allowed to create a copy of the actual >>> parameter. >> >> Huh? Do you mean that this "D" parameter may be passed by copy? But >> "Derived" is a tagged type, and tagged types are passed by reference, not >> by copy. Or so I thought. > > I think he means that the accessibility level of a parameter is that of a > local object, as it *might* have been passed by copy. Well, I had forgotten that tagged types are by reference, so I meant it might _actually_ be passed by copy. But apparently the compiler isn't taking advantage of the fact that tagged types are by reference, and is taking the more conservative view that it might be passed by copy. > (There are no special rules here for tagged types.) So when you pass > it to an access parameter, you get local accessibility and any > attempt to use it with a named access type is going to fail a > run-time accessibility check (raising Program_Error). Now I'm confused. Here's the relevant code: package Bug is -- Base interface type Listener is interface; type Listener_Ref is access all Listener'Class; procedure Process (L : in out Listener) is abstract; -- Base class type Base is tagged null record; type Base_Ref is access all Base'Class; procedure Foreach (B : access Base; I : Integer); -- Derived class type Derived is new Base and Listener with null record; type Derived_Ref is access all Derived'Class; overriding procedure Process (D : in out Derived); procedure Main; end Bug; -------------------------------------------------------------------------- with Ada.Text_IO; package body Bug is procedure Foreach (B : access Base; I : Integer) is BB : Base_Ref; begin Ada.Text_IO.Put_Line ("Foreach" & Integer'Image (I)); BB := B.all'Access; -- Line that fails end Foreach; procedure Process (D : in out Derived) is begin Ada.Text_IO.Put_Line ("Process"); D.Foreach (2); end Process; procedure Main is G_Derived : constant Derived_Ref := new Derived; G_Listener : constant Listener_Ref := Listener_Ref (G_Derived); begin Ada.Text_IO.Put_Line ("Main"); G_Derived.Foreach (1); -- This one works G_Listener.Process; -- This one fails end Main; end Bug; The problem seems to be that the call in Main: G_Listener.Process; is passing a object (of a tagged type) to an "in out" parameter to Process. Then the body of Process does 'Access on that parameter. I had thought that part of the reason tagged types were by reference was to allow this to work. I gather you are saying that's not true, or at least the actual rules did not achieve this desire. > The only way that we could have done better would be to pass an > accessibility level with every tagged parameter. That seems like way too > much overhead. I see. So the rules are more conservative than they could be, leading to programmer surprises like this one. Except that I'm not clear how accessiblity information is passed now. Since it's a runtime check, it seems the accessiblity level must be stored with the access object somehow; what is the extra overhead you are talking about? > You can use 'Unchecked_Access to get around the accessibility check, of > course, but if it would have failed, there is a chance that you will have > done something that would actually create a dangling pointer. Right. I really appreciate the compiler telling me how to avoid possible dangling pointers. So far, I've managed to write code that follows the Ada rules (without Unchecked_Access), and still does what I want. So the current Ada rules work for me :). > The aliased parameters that we're looking to add to Ada will mitigate this > problem somewhat, but only a little. Which Ada Issue is this in? I tried searching at http://www.ada-auth.org/search-ai05s.html, but I with Firefox only get a blank screen in response. MS Internet Explorer gives a results page. But there are lots of results for 'aliased parameter', and none for '"aliased parameter"'. Ah; searching the index page for 'aliased' finds AI05-0142, which seems to be it. I think that would allow the above code to work, by adding 'aliased' to Process: overriding procedure Process (D : aliased in out Derived); Hmm, that AI contains this paragraph: AARM Ramification: Tagged objects (and tagged aggregates for in parameters) do not need to be aliased. This matches the behavior of unaliased formal parameters of tagged types, which allow 'Access to be taken of the formal parameter regardless of the form of the actual parameter. Which says the code above should not raise an accessibility error. It seems like this paragraph is referening to the Ammendment 1 Ada behavior. But maybe it's just wrong? Hmm. Searching thru the AARM, I find: 3.10 9.l/2 We considered making more kinds of objects aliased by default. In particular, any object of a by-reference type will pretty much have to be allocated at an addressable location, so it can be passed by reference without using bit-field pointers. Therefore, one might wish to allow the Access and Unchecked_Access attributes for such objects. However, private parts are transparent to the definition of "by-reference type", so if we made all objects of a by-reference type aliased, we would be violating the privacy of private parts. Instead, we would have to define a concept of "visibly by-reference" and base the rule on that. This seemed to complicate the rules more than it was worth, especially since there is no way to declare an untagged limited private type to be by-reference, since the full type might by nonlimited. which says "aliased" is _not_ the same as "by reference", and gives a rationale for not allowing 'Access on by reference types. But then: 3.10.2 26.f Note that for objects of a by-reference type, it is not an error for a programmer to take advantage of the fact that such objects are passed by reference. ... And finally in the definition of 'Access: Annex K 4 X'Access For a prefix X that denotes an aliased view of an object: ... "aliased" is not the same as "by reference" I can see why this is complicated :) Incidently, I first tried getting to the Ada Issues site via AdaIC, but couldn't find a link. I expected one on the Working Groups or Ada Standards page. -- -- Stephe