Version 1.5 of ais/ai-00263.txt

Unformatted version of ais/ai-00263.txt version 1.5
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.

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

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).

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


Questions? Ask the ACAA Technical Agent