Version 1.5 of ais/ai-00034.txt

Unformatted version of ais/ai-00034.txt version 1.5
Other versions for file ais/ai-00034.txt

!standard 03.02 (09)          00-01-24 AI95-00034/04
!class ramification 95-06-25
!status Response 2000 00-01-24
!status WG9 approved 96-12-07
!status ARG Approved (subject to editorial review) 9-0-2 96-10-07
!status work item 95-10-12
!status received 95-06-25
!priority Medium
!difficulty Hard
!qualifier Clarification
!subject Unconstrained Formal types
!summary
A formal private subtype without discriminants is constrained.
An access subtype may be doubly constrained in a generic instance; the constraint given in the subtype_indication overrides the constraint (if any) that might have come from the actual subtype.
!question
When is a generic formal subtype unconstrained?
AARM-12.3(11.c) says:
A formal derived subtype is constrained if and only if the ancestor subtype is constrained. A formal array type is constrained if and only if the declarations says so. Other formal subtypes are unconstrained, even though they might be constrained in an instance.
However, this does not seem to follow from the RM rules.
!response
3.2(9) says:
A subtype is called an unconstrained subtype if its type has unknown discriminants, or if its type allows range, index, or discriminant constraints, but the subtype does not impose such a constraint; otherwise, the subtype is called a constrained subtype (since it has no unconstrained characteristics).
Note the distinction between "type" and "subtype". An array type allows an index constraint, for example, whereas an array subtype may or may not impose one.
Thus, AARM 12.3(11.c) is incorrect in the case of a subtype of a formal private type with no discriminants. Such a subtype is constrained, because its type does not allow a discriminant constraint.
This raises an interesting question:
generic type Str_Ptr is access String; package GP is ... end GP;
package body GP is subtype Str_Ptr_10 is Str_Ptr(1..10); -- Legal? (Yes.) X : Str_Ptr_10; ... end GP;
Str_Ptr is unconstrained, since an access type designating String allows a constraint, and Str_Ptr does not impose one. This implies that 3.7.1(7) allows the subtype_indication "Str_Ptr(1..10)". However, the instance might try to impose a different constraint:
type Str_P is access String; subtype Str_P_7 is Str_P(1..7);
package P is new GP(Str_P_7); -- Legal? (Yes.)
12.3(11) says this is legal, since Legality Rules are not enforced in the body of an instance. Thus, the bounds of X are (1..10), and the constraint (1..7) is effectively ignored.
Note that if the declaration of Str_Ptr_10 were in the declaration of GP instead of the body, then the instantiation P would be illegal, since Legality Rules are enforced in the instance declaration.
Note that if the two constraints ever "meet", Constraint_Error will be raised, as illustrated by the following modification of the above example:
generic type Str_Ptr is access String; type Obj: in out Str_Ptr; package GP is procedure Bad; end GP;
package body GP is subtype Str_Ptr_10 is Str_Ptr(1..10); S: aliased String(1..10); X: Str_Ptr_10 := S'access;
procedure Bad is begin Obj := X; -- Constraint_Error is raised here. end Bad; end GP;
type Str_P is access String; subtype Str_P_7 is Str_P(1..7); Actual_Obj: Str_P_7;
package P is new GP(Str_P_7, Actual_Obj); ... P.Bad; -- This will propagate Constraint_Error.
In the instance, Obj is constrained to (1..7), whereas X is constrained to (1..10). An attempt to assign one to the other (as in procedure Bad) will fail the constraint check.
An alternative rule would be that it is illegal to give a constrained access subtype as the actual in the above case. This would be a cleaner rule, since it would avoid the anomaly of a doubly-constrained access type. However, most Ada 83 compilers probably allow the above example, and make the bounds of X be (1..10), and since constraining an access subtype is fairly uncommon, it does not seem worthwhile to use this alternative rule.
Note that it is irrelevant whether a formal scalar subtype is considered constrained or unconstrained, since no compile-time rules are affected. Constrained-ness of a scalar type has an effect at run-time, but at run-time, only instances exist, not generic units.
!ACATS test
A C-Test should be created out of the examples in this AI.
!appendix

!section 3.2(9)
!subject Unconstrained Formal types
!reference AARM-3.2(9);6.0
!from Jesper Joergensen 95-03-31
!keywords Unconstrained, Formal type
!reference as: 95-5109.a Jesper Joergensen 95-3-31>>
!discussion

I have problems determining when a formal type is unconstrained. Paragraph
12.3(11c) says that all kinds of formal types except derived and arrays are
unconstrained, but this is only a ramification so where is the proof for this?
There are various definitions for "unconstrained" in chapter 3 that could be
taken as covering the formal type case too, but then there is inconsistency.
A private type declaration without any discriminant part, for instance, is
defined by 3.2(9) to be constrained, whereas 12.3(11c) says it is
unconstrained.

/Jesper

****************************************************************

!section 3.2(9)
!subject Unconstrained Formal types
!reference AARM-3.2(9);6.0
!reference 95-5109.a Jesper Joergensen 95-03-31
!keywords Unconstrained, Formal type
!from Tucker Taft 95-03-31
!reference as: 95-5111.a Tucker Taft 95-3-31>>
!discussion

> I have problems determining when a formal type is unconstrained. Paragraph
> 12.3(11c) says that all kinds of formal types except derived and arrays are
> unconstrained, but this is only a ramification so where is the proof for this?
> There are various definitions for "unconstrained" in chapter 3 that could be
> taken as covering the formal type case too, but then there is inconsistency.
> A private type declaration without any discriminant part, for instance, is
> defined by 3.2(9) to be constrained, whereas 12.3(11c) says it is
> unconstrained.

Agreed.  12.3(11c) is in error for those types whose subtypes are always
constrained per 3.2(9) because the type does not allow range, index,
or discriminant constraints.

A more interesting issue is formal access (sub)types whose designated
subtype is unconstrained.  12.3 implies that these are unconstrained
(if the type allows constraints), even if the actual subtype is constrained.

For example:

    generic
        type Str_Ptr is access String;
    package GP is
        subtype Str_Ptr_5 is Str_Ptr(1..5);
        ...
    end GP;

    package body GP is
        subtype Str_Ptr_10 is Str_Ptr(1..10);
        X : Str_Ptr_10;
        ...
    end GP;

Now suppose we instantiate GP with a constrained subtype of
an access-to-string type:

    type Str_P is access String;
    subtype Str_P_7 is Str_P(1..7);

    package P is new GP(Str_P_7);

According to 12.3, it seems pretty clear that this instantiation
should fail because of the declaration of Str_Ptr_5 in the visible
part of GP (access types cannot be "doubly" constrained -- see 3.6.1(5)
and 3.7.1(7)).

However, if the declaration of Str_Ptr_5 were removed, then this instantiation
would be legal, according to 12.3(11) and 12.5.4(3-5), despite the
declaration of Str_Ptr_10 in the generic body.  This seems a bit surprising,
to say the least.

Note that this same situation exists in Ada 83, but since the Ada 83
contract model was not as strict, presumably Ada 83 compilers
were supposed to complain about the declaration of Str_Ptr_10 upon
instantiation.  I doubt that many did, because I have never seen
it on the list of Ada 83 generic contract model breakages.

There seem various solutions to this problem.  One is to ignore it ;-).
But of course, now that it has been mentioned, we can't really do that.

One "real" solution would be to require that an actual access subtype in
an instantiation be unconstrained if the formal access subtype
is unconstrained.  A second would be to define the semantics
of a "double" constraining of an access type to be equivalent to
just applying the "second" constraint.  I suspect that most Ada 95
compilers (and probably most Ada 83 compilers as well ;-) would
currently use this latter solution (or die horribly).
Since this latter solution is the most flexible, though admittedly
a bit odd, we might as well leave things as they are (with perhaps
a note confirming what it means).

Disallowing instantiation with constrained access subtypes in such a
case seems a bit like overkill, particularly since it is not upward
compatible (though I'm not sure anyone would notice either way, given
how rarely access subtypes are ever declared).

> /Jesper

-Tuck

****************************************************************

!section 3.2(9)
!subject Unconstrained
!reference AARM-3.2(9);6.0
!reference 95-5111.a Tucker Taft 95-03-31
!from Jesper Joergensen 95-04-03
!reference as: 95-5113.a Jesper Joergensen 95-4-3>>
!discussion

Your example on a formal access type whose designated subtype is unconstrained
is indeed very interesting, but I am still in doubt on the more simple cases:

1. 3.2(9) says that a type is unconstrained if it allows an index constraint,
   for example. But 3.6.1 says that such an index contstraint is allowed if
   the array subtype is unconstrained. Thus we have a circular definition, i.e
   no definition. Same problem with 3.7.1(7), or am I missing some other
   paragraph that is actually saving us?

2. For formal scalar types, where does the manual say that they are
   unconstrained? 12.5.2 says nothing about this and e.g. 3.5.4(9) only talks
   about the syntactic unit signed_integer_type_definition, not
   formal_signed_integer_type_definition. Is it implicit in the fact that
   nowhere it is said that a formal_signed_integer_type_definition defines a
   constrained first subtype?

Regarding your two proposals on solution to the "access to unconstrained"
problem I think that to require the actual to be unconstrained if the formal
is, is a good solution that matches the array and private cases. The other
solution is impossible to implement in the compiler alone (when the linker
instantiates the body it must also check for this). I agree with your last
remark that nonone would notice either way!

/Jesper


****************************************************************

!section 3.2(9)
!subject Unconstrained
!reference AARM-3.2(9);6.0
!reference 95-5111.a Tucker Taft 95-03-31
!reference 95-5113.a Jesper Joergensen 95-04-03
!from Tucker Taft 95-04-03
!reference as: 95-5114.a Tucker Taft 95-4-3>>
!discussion

> Your example on a formal access type whose designated subtype is unconstrained
> is indeed very interesting, but I am still in doubt on the more simple cases:
>
> 1. 3.2(9) says that a type is unconstrained if it allows an index constraint,
>    for example. But 3.6.1 says that such an index contstraint is allowed if
>    the array subtype is unconstrained. Thus we have a circular definition, i.e
>    no definition.

This is not quite circular.  The distinction between *type* and *subtype*
is important here.  3.2(9) says that a *subtype* is unconstrained if its
*type* allows an index/discrim/range constraint, but the *subtype* does
not impose one.  All array types "allow" an index constraint.
Only some array *subtypes* impose one.  3.6.1 says that an index constraint
in a subtype_indication is only permitted if the *subtype* does not
already impose an index constraint.

> ... Same problem with 3.7.1(7), or am I missing some other
>    paragraph that is actually saving us?

It is important to notice that 3.2(9) distinguishes between types
and subypes.

> 2. For formal scalar types, where does the manual say that they are
>    unconstrained? 12.5.2 says nothing about this and e.g. 3.5.4(9) only talks
>    about the syntactic unit signed_integer_type_definition, not
>    formal_signed_integer_type_definition. Is it implicit in the fact that
>    nowhere it is said that a formal_signed_integer_type_definition defines a
>    constrained first subtype?

There is very little difference at compile-time between a constrained and
unconstrained scalar subtype.  The same attributes (e.g. 'First and 'Last)
are defined for both.  The primary difference between constrained and
unconstrained for scalar subtypes is whether a range constraint
is checked at run-time.  Since run-time only applies to instances,
this difference doesn't matter for formal scalar subtypes.

Whether a formal scalar subtype is constrained could affect static
subtype matching rules, and static compatibility in the context of
a formal derived type.  However, static matching is not a problem because
static matching requires type matching, and because al formal scalar
subtypes are never static, also requires that any constraint arise
from the same subtype_indication.  This can be checked without
knowing whether or not the formal scalar subtype is constrained.
The same logic applies to static compatibility, since if the
subtypes are not static, their constraints must arise from the same
subtype_indication.

In any case, I would agree that the "ramification" given in 12.3(11.c)
seems a bit hard to prove.

> Regarding your two proposals on solution to the "access to unconstrained"
> problem I think that to require the actual to be unconstrained if the formal
> is, is a good solution that matches the array and private cases. The other
> solution is impossible to implement in the compiler alone (when the linker
> instantiates the body it must also check for this).

I'm not sure I understand.  I did not mean to propose that the instance
would be illegal if the body included a constraint on a formal access
subtype.  Rather, I proposed that the language would define the
constraint imposed on the formal subtype in the body to take precedence over
the one coming from the actual subtype.  I presume this is what
most Ada 83 compilers do today (though I haven't checked).

> ... I agree with your last
> remark that nonone would notice either way!

Except us language lawyers, of course.

> /Jesper

-Tuck

****************************************************************

!section 03.02(09)
!subject Unconstrained Formal types
!reference RM95-03.02 (09)
!reference AI95-00034
!from Pascal Leroy 95-10-09
!reference as: 95-5318.d Pascal Leroy 95-10-9>>
!discussion

This AI has an example that completely confuses me (and a number of my
colleagues):

generic
        type Str_Ptr is access String;
package GP is
end GP;

type Str_P is access String;
subtype Str_P_7 is Str_P(1..7);
package P is new GP(Str_P_7); -- Legal? (Yes.)

12.5.4(3) says that "for a formal access-to-object type, the designated
subtype of the formal and the actual types shall statically match."

The designated subtype of the formal is clearly String.  I would guess that
the designated subtype of Str_P_7 is String(1..7), but I was unable to deduce
that from the RM.

4.9.1(2) says that "a subtype statically matches another subtype ... if they
have statically matching constraints."

It's a bit unclear how this rule applies to an unconstrained subtype, but it
seems safe to say that the constraint of String doesn't statically match that
of String (1..7).

So why is it that the instantiation above is legal?

****************************************************************

!section 03.02(09)
!subject Unconstrained Formal types
!reference RM95-03.02 (09)
!reference AI95-00034
!reference 95-5318.d Pascal Leroy 95-10-9
!from Bob Duff
!reference as: 95-5324.b Robert A Duff 95-10-11>>
!discussion

> This AI has an example that completely confuses me (and a number of my
> colleagues):
>
> generic
>       type Str_Ptr is access String;
> package GP is
> end GP;
>
> type Str_P is access String;
> subtype Str_P_7 is Str_P(1..7);
> package P is new GP(Str_P_7); -- Legal? (Yes.)
>
> 12.5.4(3) says that "for a formal access-to-object type, the designated
> subtype of the formal and the actual types shall statically match."
>
> The designated subtype of the formal is clearly String.  I would guess that
> the designated subtype of Str_P_7 is String(1..7), but I was unable to deduce
> that from the RM.

The actual *type* is the type of Str_P, and its designated subtpe is
String.  This follows directly from 3.10(10).  We don't talk about
designated subtypes of access SUBtypes.

> 4.9.1(2) says that "a subtype statically matches another subtype ... if they
> have statically matching constraints."
>
> It's a bit unclear how this rule applies to an unconstrained subtype, but it
> seems safe to say that the constraint of String doesn't statically match that
> of String (1..7).
>
> So why is it that the instantiation above is legal?

The designated subtypes are both String, and String statically matches
itself.

- Bob

****************************************************************

Questions? Ask the ACAA Technical Agent