I stumbled on a curious fact.....
Is this a compiler bug or intentional language design? Any language
lawyers?
I stumbled on a curious fact.
The value of an object with a discriminant can be changed to a value with a different discriminant if the type's discriminants are defaulted.
Right?
Wrong! Not through an access type!
procedure Test is
type F is (F1, F2, F3);
type Foo (K : F := F1) is record
case K is
when F1 =>
X1 : Integer;
when F2 =>
X2 : Float;
when F3 =>
X3 : String (1..2);
end case;
end record;
type Foo_Ptr is access all Foo;
X : aliased Foo;
P : Foo_Ptr := X'Access;
begin
X := (F2, 1.0); -- OK
P.all := (F1, 3); -- Error!
end Test;
Some experiments point at the general access type.
type Foo_Ptr is access Foo; -- sans `all`
X : Foo;
P : Foo_Ptr := new Foo;
type Foo1 is new Foo_Ptr (K => F1);
begin
X := (F2, 1.0); -- OK
P.all := (F1, 3); -- _no_ Error!
Foo1 (P).all := (F1, 3);
end Test;
(Doesn't rejection for general access types seem reasonable
if assignment would otherwise require adjusting the storage
layout of a variable, including all access paths to components?
Just guessing.)
I stumbled on a curious fact.
The value of an object with a discriminant can be changed to a value
with a different discriminant if the type's discriminants are defaulted.
Right?
Wrong! Not through an access type!
Is this a compiler bug or intentional language design? Any language
lawyers?
I do hope, this answers the question:
3.10(14/3) … The first subtype of a type defined by … an access_to_object_definition is unconstrained if the designated
subtype is an ... discriminated subtype; otherwise, it is
constrained.
4.8(6/3) If the designated type is composite, then … the created
object is constrained by its initial value (even if the designated
subtype is unconstrained with defaults).
Le 22/03/2023 à 10:19, Dmitry A. Kazakov a écrit :
I stumbled on a curious fact.(...)
The value of an object with a discriminant can be changed to a value
with a different discriminant if the type's discriminants are defaulted.
Right?
Wrong! Not through an access type!
Is this a compiler bug or intentional language design? Any languageAn access value is always constrained by its initial value; this is
lawyers?
necessary because of constrained access subtypes.
Here is a slightly
modified version of your example:
procedure Test is
type F is (F1, F2, F3);
type Foo (K : F := F1) is record
case K is
when F1 =>
X1 : Integer;
when F2 =>
X2 : Float;
when F3 =>
X3 : String (1..2);
end case;
end record;
type Foo_Ptr is access all Foo;
type Foo_Ptr2 is access Foo;
X : aliased Foo;
P : Foo_Ptr := X'Access;
PF2: Foo_PTR2 (F2);
begin
X := (F2, 1.0); -- OK
PF2 := new Foo (F2);
P := PF2.all'Access;
P.all := (F1, 3); -- Error!
end Test;
Without this rule, PF2.all would now designate a value whose
discriminant is F1!
Perhaps it would be better to make the assignment P := PF2.all'Access illegal, because it in effect converts a constrained access value (PF2)
to an unconstrained access subtype (P), and so in some sense violates
the prohibition of constrained subtypes of general access types.
Here is a slightly modified version of your example:
procedure Test is
type F is (F1, F2, F3);
type Foo (K : F := F1) is record
case K is
when F1 =>
X1 : Integer;
when F2 =>
X2 : Float;
when F3 =>
X3 : String (1..2);
end case;
end record;
type Foo_Ptr is access all Foo;
type Foo_Ptr2 is access Foo;
X : aliased Foo;
P : Foo_Ptr := X'Access;
PF2: Foo_PTR2 (F2);
begin
X := (F2, 1.0); -- OK
PF2 := new Foo (F2);
P := PF2.all'Access;
P.all := (F1, 3); -- Error!
end Test;
Without this rule, PF2.all would now designate a value whose
discriminant is F1!
This error is understandable and valid, because now P.all is PF2.all
which is an allocated object and therefore constrained by its initial
value with K = F2.
But why should the same apply when P designates X, which is
unconstrained? Is it just an optimization (in the RM) so that a
general access value does not have to carry around a flag showing
whether its designated object is constrained or unconstrained?
Le 23/03/2023 19:55, Niklas Holsti a crit :
Here is a slightly modified version of your example:
procedure Test is
type F is (F1, F2, F3);
type Foo (K : F := F1) is record
case K is
when F1 =>
X1 : Integer;
when F2 =>
X2 : Float;
when F3 =>
X3 : String (1..2);
end case;
end record;
type Foo_Ptr is access all Foo;
type Foo_Ptr2 is access Foo;
X : aliased Foo;
P : Foo_Ptr := X'Access;
PF2: Foo_PTR2 (F2);
begin
X := (F2, 1.0); -- OK
PF2 := new Foo (F2);
P := PF2.all'Access;
P.all := (F1, 3); -- Error!
end Test;
Without this rule, PF2.all would now designate a value whose
discriminant is F1!
This error is understandable and valid, because now P.all is PF2.all
which is an allocated object and therefore constrained by its initial
value with K = F2.
But why should the same apply when P designates X, which is
unconstrained? Is it just an optimization (in the RM) so that a
general access value does not have to carry around a flag showing
whether its designated object is constrained or unconstrained?
I didn't dig in the RM in all details, but I think this comes from the
fact that being constrained (always) is a property of the pointer (more precisely, its subtype), not of the pointed-at object.
--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX https://www.adalog.fr https://www.adacontrol.fr
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 353 |
Nodes: | 16 (2 / 14) |
Uptime: | 84:24:27 |
Calls: | 7,639 |
Files: | 12,802 |
Messages: | 5,691,882 |