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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!newsfeed0.kamp.net!newsfeed.kamp.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Unexpected discriminant check failure involving access types Date: Mon, 10 Aug 2015 22:43:43 +0300 Organization: Tidorum Ltd Message-ID: References: <55C8BBAF.90300@spam.spam> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Trace: individual.net F03oWxxsPYYtYiDIISBXWAmRHEnNByn2Nin8x7tIXvOLUWsCy3 Cancel-Lock: sha1:KeHaLrlCxuk0fvbYgTzfU+qvX50= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 In-Reply-To: <55C8BBAF.90300@spam.spam> Xref: news.eternal-september.org comp.lang.ada:27410 Date: 2015-08-10T22:43:43+03:00 List-Id: On 15-08-10 17:56 , Markus Schöpflin wrote: > Am 10.08.2015 um 16:33 schrieb Niklas Holsti: >> On 15-08-10 15:38 , Markus Schöpflin wrote: >>> Given the following piece of code: >>> >>> ---%<--- >>> 1 procedure TEST >>> 2 is >>> 3 type T is (T1, T2); >>> 4 >>> 5 type RECORD_T (X : T := T1) is record >>> 6 null; >>> 7 end record; >>> 8 >>> 9 type PTR_T is access RECORD_T; >>> 10 >>> 11 FOO : RECORD_T; >>> 12 FOO_PTR : constant PTR_T := new RECORD_T; >>> 13 >>> 14 FOO1 : constant RECORD_T := (X => T1); >>> 15 FOO2 : constant RECORD_T := (X => T2); >>> 16 begin >>> 17 FOO := FOO1; >>> 18 FOO := FOO2; >>> 19 >>> 20 FOO_PTR.all := FOO1; >>> 21 FOO_PTR.all := FOO2; >>> 22 end; >>> --->%--- >>> >>> When compiled and executed, I get: >>> >>> > ./test >>> >>> raised CONSTRAINT_ERROR : test.adb:21 discriminant check failed >>> >>> Can anyone please explain me why I get a discriminant check error when >>> using access types? I would have expected it to work the same as for the >>> non-access case. >> >> This is a consequence of RM 4.8(6/3): "... If the designated type >> is composite, then the subtype of the created object is the >> designated subtype when the designated subtype is constrained or >> there is an ancestor of the designated type that has a constrained >> partial view; otherwise, the created object is constrained by its >> initial value (even if the designated subtype is unconstrained with >> defaults)." >> >> In other words, the object FOO_PTR.all is constrained and it is >> not possible to change its discriminants -- the default value given >> to the discriminant X, which means that FOO is unconstrained, does >> not have the same effect on an allocated object. > > OK, understood. > >> The AARM motivates this rule as follows: "All objects created by >> an allocator are aliased, and most aliased composite objects need >> to be constrained so that access subtypes work reasonably." In >> other words, there could be a declarations like >> >> type PTR_T1_T is access all RECORD_T (X => T1); >> FOO_T1_PTR : PTR_T1_T; >> >> and statements >> >> FOO_T1_PTR := PTR_T1_T (FOO_PTR); >> >> Now FOO_PTR and FOO_T1_PTR point to the same object (the allocated >> one), with X = T1. If the program could now change FOO_PTR.all.X to >> T2, the subtype of FOO_T1_PTR would be a lie, because the >> referenced object would now have X = T2. > > Makes sense. But right now I'm surprised that > > FOO_T1_PTR := PTR_T1_T (FOO_PTR); > > is actually allowed. The access-type conversion involves a run-time check that FOO_PTR.all satisfies the constraints for the designated type of PTR_T1_T, that is, that FOO_PTR.all.X = T1. I think this is specified in RM 4.6(50): "... any checks associated with evaluating a conversion to the target designated subtype are performed." Constraint_Error results if the check fails. > Consider: > > FOO : aliased RECORD_T; > FOO_T1_PTR : PTR_T1_T := PTR_T1_T'(FOO'Access); > > There you get the (expected) error that the "object subtype must > statically match the designated subtype". That's a qualified expression, not a type conversion. I suppose that explains the difference. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .