!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. **************************************************************** From: Steve Baird Sent: Thursday, May 31, 2001 12:20 PM At the last ARG meeting, there was general agreement that the phrase "formal scalar type" in the second sentence of 4.9(26) should be replaced with "formal type". The analogous question for static string subtypes was not resolved. It was observed that the two cases of a formal array type and a formal derived array type ought to be treated consistently, but it was not obvious whether they both should be defined to be static or non-static. For example, either both or neither of the following two named number declarations should be legal: type T is array (Character) of Character; generic type Ft1 is array (Character) of Character; type Ft2 is new T; package G is Length_1 : constant := Ft1'Length; Length_2 : constant := Ft2'Length; end G; It was suggested that that broadening the definition of a static string subtype rather than narrowing it would not cause problems because the matching rules (12.5.1(8), 12.5.3(6)) would ensure that the FIRST, LAST, and LENGTH attributes of the actual subtypes would match those of the formal. This appears to be true, but there may still be reasons for restricting the definition. A string literal of a static string subtype is a static expression. Would it pose difficulties for a shared code generic implementation if the representation of a static expression varied among instantiations? This could occur if the actual types were subject to different representation specifications. For example: package Foo is subtype Index is Integer range 1 .. 3; type T is array (Index) of Character; for T'Component_Size use Character'Size; generic type Ft1 is array (Index) of Character; type Ft2 is new T; package G is Lit1 : constant Ft1 := "123"; Lit2 : constant Ft2 := "123"; end G; type D is new T; for D'Component_Size use 2 * Character'Size; package I1 is new G (T, T); package I2 is new G (D, D); end Foo; My guess is that this is not a problem. Another argument for the more restrictive definition is consistency with the scalar case. I don't think these arguments are persuasive; I suggest that the definition of static string subtype be broadened by deleting the text "(and whose type is not a descendant of a formal array type)" from 4.9(26). Comments? **************************************************************** From: Randy Brukardt Sent: Friday, June 1, 2001 7:40 PM Sigh. These gung-ho new members; they don't even let us catch our breath. :-) > This appears to be true, but there may still be reasons > for restricting the definition. A string literal of a > static string subtype is a static expression. Would it pose > difficulties for a shared code generic implementation if > the representation of a static expression varied among > instantiations? This could occur if the actual types > were subject to different representation specifications. > ... > My guess is that this is not a problem. I don't think the representations is a problem. Any string literal can have different representations. Janus/Ada generates these things at runtime. I don't think that the fact that they are defined to be static makes any difference. Janus/Ada has no problem compiling the above program; I don't think that the staticness (or lack of it) matters in this example. It would be more interesting if the constants were then used in a pragma Import, but again, the representation of the static expression isn't necessarily the same as that of the runtime object, so there isn't any problem. > I don't think these arguments are persuasive; I suggest that > the definition of static string subtype be broadened by deleting the text > "(and whose type is not a descendant of a formal array type)" > from 4.9(26). Seems OK to me. Assuming that static strings can't be used in a context where the component representation matters (which I believe to be the case). ****************************************************************