From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: Unexpected discriminant check failure involving access types
Date: Mon, 10 Aug 2015 22:43:43 +0300
Date: 2015-08-10T22:43:43+03:00 [thread overview]
Message-ID: <d2sd7fFe8ocU1@mid.individual.net> (raw)
In-Reply-To: <55C8BBAF.90300@spam.spam>
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
. @ .
prev parent reply other threads:[~2015-08-10 19:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-10 12:38 Unexpected discriminant check failure involving access types Markus Schöpflin
2015-08-10 13:14 ` Mark Lorenzen
2015-08-10 14:20 ` Markus Schöpflin
2015-08-10 19:00 ` Randy Brukardt
2015-08-10 14:33 ` Niklas Holsti
2015-08-10 14:56 ` Markus Schöpflin
2015-08-10 19:43 ` Niklas Holsti [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox