Version 1.2 of acs/ac-00085.txt

Unformatted version of acs/ac-00085.txt version 1.2
Other versions for file acs/ac-00085.txt

!standard 12.04(08)          03-12-05 AC95-00085/01
!class amendment 03-12-05
!status received no action 03-12-05
!status received 03-10-15
!subject Can't pass limited constants into a generic
!summary
!appendix

From: Craig Carey
Sent: Wednesday, October 15, 2003  2:44 AM

This might be under AI-00318 ("Returning [limited] objects without copying").

However this on no being able to pass limited types in, and that AI is
on not being able to pass them out satisfactorily.


I note that this reasoning in RM 12.4 (8a) appears to unreasonable.
It is all about stopping copying.

Here is the text:

  12.4 Formal Objects

    (8.) The type of a generic formal object of mode in shall be
       nonlimited.

    (8.a) Reason: Since a generic formal object is like a constant
       of mode 'in' initialized to the value of the actual, a
       limited type would not make sense, since initializing a
       constant is not allowed for a limited type. That is, generic
       formal objects of mode 'in' are passed by copy, and limited
       types are not supposed to be copied.

     http://www.adaic.org/standards/95aarm/html/AA-12-4.html

In my code below, I can't get the number (rational number), zero, into
a generic package. Suppose the rationals were big numbers and on the
heap. Then to stop RM7.6-encouraged slowness (i.e. "new" is used so
KSLOCS of Microsoft RAM management code is called, no Assign() proc),
I made the numeric type be limited.

We can be sure that a limited type is a constant when it is created
by dereferencing an "access constant" pointer. That is done in the
code below.

I would describe paragraph 12.4(8a) as arguing like this:

(1) no comment on how vendors don't agree that the restriction is
  common sense

(2) the text says initializing must not occur. [Actually, a good
  argument would consider the two case. It seems that the problem
  that is supposed to be avoided, is actually absent from both
  cases.] So a premise of the argument is irrelevant and a question
  that arises is wether the argument is well designed.

(3) The argument talks about the idea that "common sense" is
  appropriate.

(4) The idea I thought irrelevant, i.e. of copying fields when none
  occurs in both cases, is emphasized again at the end with the
  words "and limited types are not supposed to be copied".


Paragraph 12.4(8a) seems to be clueless: it talks about copying
and initializing stopping a good design without ruling out this
case: such copying is absent in both a fixed designed and the current
design. I.e. pointers are passed in when constant limited private
types are supplied, just like what happens with procedures.


-----------------
with Text_IO;

procedure P is
   -------------------------
   generic
      type Num is limited private;  --  No RM7.6 ":=" slowdowns allowed
      type Num_Const_Ptr is access constant Num;
      Zero_Const_Ptr    : Num_Const_Ptr;
      --  Zero              : in Num;   -- Illegal

      with procedure Assign (LHS : out Num; RHS : Num);

   package Rationals is
      procedure Test_RM1248a (
               LHS      : out Num;
               RHS      : Num := Zero_Const_Ptr.all);

         --  In the code line above, there is an assignment of
         --  a limited private record using the 'in' mode type.
         --  Such assignments can "in general" occur immediately
         --  before and after the generic formal part, but not
         --  in there.

   end Rationals;

   package body Rationals is
      procedure Test_RM1248a (
               LHS      : out Num;
               RHS      : Num := Zero_Const_Ptr.all) is
      begin
         Assign (LHS, RHS);
      end Test_RM1248a;
   end Rationals;
   -------------------------
   package Misc is
      Sint        : aliased Integer := 54_321;

      type Integer_Ptr is access constant Integer;

      type Num is tagged
         limited record
            Num, Den    : Integer_Ptr := Sint'Access;
            RO          : Boolean;     --  = say if ptrs are copies
         end record;

      type Num_Const_Ptr is access constant Num;

      procedure Assign (LHS : out Num; RHS : Num);
      Zero_Value     : aliased Num;

      --  Zero           : aliased constant Num;

      package Math is new Rationals (
                  Num => Num,
                  Num_Const_Ptr => Num_Const_Ptr,
                  Zero_Const_Ptr => Zero_Value'Access,
                  Assign => Assign);
   private
      --  Zero : aliased constant Num := ...  --  Desirable and illegal,
                                     --  can't initalize limited consts
   end Misc;

   package body Misc is
      procedure Assign (LHS : out Num; RHS : Num) is
      begin
         LHS.Num := RHS.Num;
         LHS.Den := RHS.Den;
         LHS.RO := True;
      end Assign;
   begin
      Zero_Value.Num := new Integer'(0);
      Zero_Value.Den := new Integer'(1);
      Zero_Value.RO := True;
   end Misc;
   -------------------------
   X        : Misc.Num;
begin

   Misc.Math.Test_RM1248a (LHS => X);

   Text_IO.Put_Line ("Result =" & Integer'Image (X.Num.all) &
            " /" & Integer'Image (X.Den.all));

   --  That prints the line "Result = 0 / 1" as expected.

   --  Hence that assignment of a constant limited private
   --  parameter did occur in the call of Test_RM1248a.
end P;


Mr Duff of AI-00318 wrote that less than 1% of his problems with
limited types are due to be unable to assign constants. If getting
data in is so much less important than getting limited records out,
then another AI could be started up to keep issues of dissimilar
importance, separated.

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

From: Pascal Leroy
Sent: Tuesday, October 28, 2003  9:42 AM

I believe that AI-287 answers your concern to some extent.

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

Questions? Ask the ACAA Technical Agent