!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) @drepl A @i is either a @i or a @i. 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 @b, and the result subtype of a generic formal function, are not static. @dby A @i is either a @i or a @i. 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 @b, 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. ****************************************************************