Version 1.2 of acs/ac-00031.txt

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

!standard 12.4(10)          02-04-26 AC95-00031/01
!class confirmation 02-04-26
!status received no action 02-04-26
!subject 'ACCESS on generic formal objects
!appendix

!topic 'ACCESS on generic formal objects
!reference RM95-12.4(10,11)
!from Adam Beneschan 04-24-02
!discussion

What output should the following program generate?

----------------------------------------------------------------------
    package Pak1 is
        type Rec is tagged record
            F1 : Integer;
        end record;
        type Rec_P is access all Rec;
        type Rec_P_Const is access constant Rec;
        Test_Obj : aliased Rec;
    end Pak1;

    with Pak1;
    package Pak2 is
        generic
            GObj : Pak1.Rec;
        package GPack is
            procedure Test (Val : in Pak1.Rec_P);
        end GPack;
    end Pak2;

    with Text_IO;
    package body Pak2 is
        use type Pak1.Rec_P;
        package body GPack is
            procedure Test (Val : in Pak1.Rec_P) is
            begin
                if GObj'Access = Pak1.Rec_P_Const (Val) then
                    Text_IO.Put_Line ("Values are equal");
                else
                    Text_IO.Put_Line ("Values are not equal");
                end if;
            end Test;
        end GPack;
    end Pak2;

    with Pak1;
    with Pak2;
    package Pak3 is
        package GInst is new Pak2.GPack (Pak1.Test_Obj);
    end Pak3;

    with Pak1;
    with Pak3;
    procedure Test4 is
    begin
        Pak3.GInst.Test (Pak1.Test_Obj'access);
    end Test4;
----------------------------------------------------------------------

I believe it should generate "Values are not equal", because when
Test_Obj is used as a generic formal parameter to GInst, it is passed
by copy, and therefore the 'Access of GInst.GObj will not be the same
as that of Pak1.Test_Obj.  RM95 12.4(10,11) seem to make it clear that
GObj is a constant whose initial value is the value of Test_Obj, and
is not a view of Test_Obj.  However, if GObj is declared as an "in
out" generic formal parameter (and the conversion to Rec_P_Const in
the Test procedure is removed), the program should output "Values are
equal".  In fact, GNAT matches my expectations in both cases.

The reason for my confusion, though, is the comments in ACATS test
b3a2011 (I am not questioning the correctness of the test, since my
initial impression is that errors should occur on the lines marked as
errors but for different reasons).  In b3a2011, a generic is defined:

    generic
       type Gen_Tag is tagged private;
       type FormalAccType_for_Obj is access constant Gen_Tag;
       An_Obj   : Gen_Tag;
       type FormalAccType_for_Ren is access constant Gen_Tag;
       Ren_Obj  : Gen_Tag;
       type FormalAccType_for_Conv is access constant Gen_Tag;
       Conv_Obj : Gen_Tag;
    package B3A2011_1 is
       type New_FormalAccType_for_Obj is new FormalAccType_for_Obj;
       Ren : Gen_Tag renames Ren_Obj;
    private
       GAcc1 : FormalAccType_for_Obj     := An_Obj'Access;
       GAcc2 : New_FormalAccType_for_Obj := An_Obj'Access;
       ARen  : FormalAccType_for_Ren     := Ren'Access;
       AConv : FormalAccType_for_Conv    := Gen_Tag(Conv_Obj)'Access;
    end B3A2011_1;

Later, this package is instantiated:

    package Inst_L1_OK is
      new B3A2011_1 (B3A2011_0.Tag_Desig,
                     Acc_to_Tag_L1,
                     B3A2011_0.TObj1_L0,
                     Acc_to_Tag_L1,
                     TObj1_L1,
                     Acc_to_Tag_L1,
                     B3A2011_0.TObj2_L0);                             -- OK.
    -- In the private part of Inst_L1_OK, after the above instantiation:
    -- GAcc1 : Acc_to_Tag_L1 := TObj1_L0'Access;
    -- GAcc2 : Acc_to_Tag_L1 := TObj1_L0'Access;
    -- ARen  : Acc_to_Tag_L1 := TObj1_L1'Access;
    -- AConv : Acc_to_Tag_L1 := B3A2011_0.Tag_Desig(TObj2_L0)'Access;

where these relevant declarations appear at other places in the
source:

   type Acc_to_Tag_L1 is access constant B3A2011_0.Tag_Desig;
   TObj1_L0 : aliased Tag_Desig;
   TObj2_L0 : aliased Tag_Desig;
   TObj1_L1 : aliased B3A2011_0.Tag_Desig;

The comments don't match my understanding of what RM95 12.4 requires.
The comments say, for instance, that GAcc1 will be initialized to
TObj1_L0'Access; but my understanding of the language is that GAcc1
will be initialized to the 'Access of some other object whose value is
copied from TObj1_L0, not to TObj1_L0'Access.

Is my understanding of the language rules correct?  Or am I missing
something?

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

From: Robert Dewar
Sent: Wednesday, April 24, 2002  10:00 PM

Surely ADA-COMMENT is not the place to aski miscellaneous Ada programming
questions!

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

From: Randy Brukardt
Sent: Thursday, April 25, 2002  4:53 PM

> The reason for my confusion, though, is the comments in ACATS test
> b3a2011 (I am not questioning the correctness of the test, since my
> initial impression is that errors should occur on the lines marked as
> errors but for different reasons).

This looks more like a question on an ACATS test rather than one on the
standard. Surely you don't believe some random test program's comments are
more likely to be correct than the standard??

I'd suggest sending a question on the test to the ACAA mailing list (since
it isn't a formal test dispute, since your only problem is with some
comments).

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

From: Adam Beneschan
Sent: Thursday, April 25, 2002  5:02 PM

Actually, I believed it possible that a test program's comments could
be more correct than my (possible mis-)interpretation of the standard.
I've gotten pretty good at misinterpreting the RM.  But if you're
confirming that my interpretation was correct, that's really all I
needed to know.

Thanks for your response.

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

From: Randy Brukardt
Sent: Thursday, April 25, 2002  5:15 PM

I think you did a fine job of figuring out the answer from the RM. 12.4(10)
is crystal-clear that it is a new (different) object, and thus the 'Access
values should not be equal.

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

From: Robert Dewar
Sent: Thursday, April 25, 2002  10:42 PM

Comparing access values for equality like this is bogus, since a garbage
collected implementation might change access values at any point.

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

From: Robert A. Duff
Sent: Friday, April 26, 2002  9:06 AM

No, that's can't be right!  Two access values are equal in Ada if and
only if they designate the same object.  If your GC causes that not to
work, then your GC is buggy.

The GC technology is to do this is straightforward, and has been around
since before I was born.  In Lisp, (eq x x) is always 't (true), never
nil.  And (eq x y) is 't if and only if x and y designate the same
object.  The eq function is quite commonly used in Lisp, and it works as
expected, despite the presence of GC.  And Lisp is older than I.  ;-)

It's true that object addresses can change due to GC, but never in such
a way that two different objects have the same address, and if an object
has two addresses, then eq has to deal with it (follow the forwarding
pointer, for example).

Note that a GC has to deal properly with *all* the pointers, including
compiler-generated temps held in registers and whatnot.

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

From: Randy Brukardt
Sent: Friday, April 26, 2002  1:55 PM

I concur. I wondered if "=" was well defined here myself, but I looked it up
before answering Ada, and there is no weasel words in 4.5.2(12): "Two
access-to-object values are equal if the designate the same objects, or if both
are equal to the null value of the access type." Compare that to the next
paragraph on access-to-subprogram.

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

From: Robert Dewar
Sent: Friday, April 26, 2002  2:12 PM

Interestingly this is not worded as if-and-only-if. Is that always implied?
If so, by what rule?

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

From: Robert A. Duff
Sent: Friday, April 26, 2002  7:50 PM

> Interestingly this is not worded as if-and-only-if. Is that always implied?
> If so, by what rule?

1.1.4(14.b) says:

    14.b  We often use ``if'' to mean ``if and only if'' in definitions. For
          example, if we define ``photogenic'' by saying, ``A type is
          photogenic if it has the following properties...,'' we mean that a
          type is photogenic if and only if it has those properties. It is
          usually clear from the context, and adding the ``and only if'' seems
          too cumbersome.

Of course, this is not part of the official Standard, and even if it
were, it seems to leave it up to one's imagination whether "if" means
"if" or "if and only if".  ;-)

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



Questions? Ask the ACAA Technical Agent