Version 1.4 of ais/ai-00263.txt

Unformatted version of ais/ai-00263.txt version 1.4
Other versions for file ais/ai-00263.txt

!standard 4.09 (29)          01-02-23 AI95-00263/01
!class binding interpretation 01-02-22
!status work item 01-02-22
!status received 01-02-22
!qualifier Omission
!priority Medium
!difficulty Medium
!subject Scalar formal derived types are never static
!summary
A formal derived type of a scalar is never a static subtype.
!question
If it is possible for a static expression in a generic to have a different value than the corresponding expression in some instance of the generic, then there is a language design problem.
This principle is violated for scalar generic formal derived types. Consider:
procedure Foo is type E is (Aa, Bb, Cc);
generic type D is new E'Base; package G is Last_D : constant := D'Pos (D'Last); end G;
subtype S is E range Bb .. Bb;
package I is new G (S); package J is new G (E); begin null; end Foo;
I.Last_D = 2, while J.Last_D = 3. The value of Last_D is static, but depends on the instantiation.
Note that the principle can be violated even when the derived type is constrained. For instance:
procedure Fooey is
generic type D is new Integer; package G is D_Alignment : constant := D'Alignment;
end G;
type Byte_Aligned_Integer is new Integer; for Byte_Aligned_Integer'Alignment use 1;
package I is new G (Byte_Aligned_Integer); package J is new G (Integer); begin
null; end Fooey;
I.D_Alignment = 1, while J.D_Alignment probably equals 4. Again, the value of a constant is static, but depends on the instantiation.
Is this an oversight? (Yes.)
!recommendation
(See summary.)
!wording
(See corrigendum.)
!discussion
An important design principle of Ada is that a static expression has the same value in all instances. 4.9(26) ensures that by declaring that descendants of formal scalar types are not static. However, this rule does not cover formal derived types that happen to be scalar. This was a clear oversight.
!corrigendum 4.9(26)
Replace the paragraph:
A static subtype is either a static scalar subtype or a static string subtype. A static scalar subtype is an unconstrained scalar subtype whose type is not a descendant of a formal scalar type, or a constrained scalar subtype formed by imposing a compatible static constraint on a static scalar subtype. A static string subtype is an unconstrained string subtype whose index subtype and component subtype are static (and whose type is not a descendant of a formal array type), or a constrained string subtype formed by imposing a compatible static constraint on a static string subtype. In any case, the subtype of a generic formal object of mode in out, and the result subtype of a generic formal function, are not static.
by:
A static subtype is either a static scalar subtype or a static string subtype. A static scalar subtype is an unconstrained scalar subtype whose type is not a descendant of a formal type, or a constrained scalar subtype formed by imposing a compatible static constraint on a static scalar subtype. A static string subtype is an unconstrained string subtype whose index subtype and component subtype are static (and whose type is not a descendant of a formal array type), or a constrained string subtype formed by imposing a compatible static constraint on a static string subtype. In any case, the subtype of a generic formal object of mode in out, and the result subtype of a generic formal function, are not static.
!ACATS test
A B-test for this should be created.
!appendix

From: Randy Brukardt
Sent: Monday, February 19, 2001 2:31 PM

Steve Baird said:

> Making all scalar formal types non-static, rather than just
> "formal scalar types", would also solve some similar problems that
> have nothing to do with enumeration type extension. Perhaps that
> warrants a separate AI.

I tend to agree (although I couldn't think of an example off-hand). Do you
have an example of a problem that occurs without enumeration type extension?
(If you do, then we probably do need an AI on this, as it would imply a bug
in the language.)

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

From: Baird, Steve
Sent: Tuesday, February 20, 2001 6:18 PM

If it is possible for a static expression in a generic to have a
different value than the corresponding expression in some instance
of the generic, then there is a language design problem.

Agreed?

This example violates this rule,

    procedure Foo is
      type E is (Aa, Bb, Cc);

      generic
          type D is new E'Base;
      package G is
          Last_D : constant := D'Pos (D'Last);
      end G;

      subtype S is E range Bb .. Bb;

      package I is new G (S);
    begin
      null;
    end Foo;

but it isn't clear whether this problem should be fixed by
changing 4.9(26) or 12.5.1(7-10).

This example also violates the rule

    procedure Foo is
	generic
	    type D is new Integer;
	package G is
	    D_Alignment : constant := D'Alignment;
	end G;

	type Byte_Aligned_Integer is new Integer;
	for Byte_Aligned_Integer'Alignment use 1;

	package I is new G (Byte_Aligned_Integer);
    begin
	null;
    end Foo;

, but it seems clear that this is a 4.9(26) problem.

For 12.5.1(7-10), it seems like it boils down a decision
about whether something like

     generic
         type D is new Integer'Base;
     package G is
     end G;

     package I is new G (Natural);

should be accepted.

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


Questions? Ask the ACAA Technical Agent