Message from discussion Problem in "X (1).Re := X (1).Re + 1"
Received: by 10.204.152.217 with SMTP id h25mr1967215bkw.3.1336426133337;
Mon, 07 May 2012 14:28:53 -0700 (PDT)
From: Adam Beneschan <a...@irvine.com>
Subject: Re: Problem in "X (1).Re := X (1).Re + 1"
Date: Mon, 7 May 2012 14:28:52 -0700 (PDT)
X-Trace: posting.google.com 1336426133 13618 127.0.0.1 (7 May 2012 21:28:53 GMT)
NNTP-Posting-Date: Mon, 7 May 2012 21:28:53 +0000 (UTC)
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=18.104.22.168;
Content-Type: text/plain; charset=ISO-8859-1
On Monday, May 7, 2012 11:53:58 AM UTC-7, ytomino wrote:
> On Tuesday, May 8, 2012 12:37:44 AM UTC+9, Adam Beneschan wrote:
> > No. But if you change the 1 to 1.0 then I think it will be OK.
> 1.0 is correct.
> > I'm not yet really familiar with the ins and outs of user-defined refer=
> > and user-defined indexing. But my guess is that the phrase in A.18.2(1=
> > that says "Reference returns an object whose discriminant is an access =
> > that designates the element designated by Position" means that Referenc=
> > can't return an object whose discriminant designates a *copy* of the el=
> > If I understand your question correctly, this means that the scenario y=
> > concerned about can't happen.
> Imagine an implementation of an reference-counted container.
> Probably, it's like below:
> function Reference (Container : Vector; Position : Cursor) return Ref_Typ=
> -- if data is shared, do copy-on-write to prepare for change
> -- (memory management and exclusive control is omitted in this pseudo=
> if Container.Data_Block.Ref_Count > 1 then
> Container.Data_Block.Ref_Count :=3D Container.Data_Block.Ref_Count =
> Container.Data_Block :=3D new Data_Block_Type'(
> Length =3D> Container.Data_Block.Length,
> Elements =3D> (1 .. Length =3D> Container.Data_Block.Elements (1=
> Ref_Count =3D> 1);
> end if;
> -- return access value designated by Position
> return (Element =3D> Container.Data_Block.Elements (To_Index (Cursor))=
> end Reference;
> And, similar copy-on-write is inserted into Replace_Element and Update_El=
> In this container, Reference copies its elements as your saying. But the =
container comes to own copied elements, and Reference returns an access val=
ue that designates the element in same area. I hope that this is allowed fo=
r effective implementations.
> Besides, if this is disallowed in Ada.Containers.Vectors, please assume m=
y original container.
> Surely you don't think that all reference-counted containers written by u=
ser are forbidden to implement user-defined indexing.
OK, I think I figured out what you were talking about. Sorry, but your ori=
ginal post seemed to use a few words (like "implemented by reference-counti=
ng") and expect that readers would fill in the rest of the details. Unfort=
unately, I'm not a mind-reader, so it took me a lot of effort to figure it =
out. Maybe others here are better mind-readers than I am. I don't know.
But I'm guessing that you're referring to an implementation where, when a c=
opy of an element is made, the implementation doesn't make a copy immediate=
ly, but rather waits until somebody tries to modify either the original or =
the copy and *then* splits off a copy. So in your example:
X(1).Re :=3D X(1).Re + 1.0;
you're assuming that X(1) was earlier created as a copy of something else--=
or that something else was created as a copy of X(1). The main ways I can =
see that this could be done are by using the Copy or Assign operations of v=
X :=3D Copy(W);
X(1).Re :=3D X(1).Re + 1.0;
so that when X is created, it's done by creating references to all the elem=
ents in W rather than by copying the elements of W; and then making a new c=
opy of an individual element when it needs to be modified. Of course, it's=
silly to do this if the element type is Complex, since it's surely easier =
to copy two floats than to implement all the overhead needed to deal with r=
eferences. But I can imagine that it might make sense if the element type =
is ... um, more complex than Complex. Or a whole lot bigger.
I'm still dubious that it can work, though. Consider:
X :=3D V.Copy(W); -- (A)
Ref1 :=3D V.Constant_Reference (W, 1); -- (B)
Ref2 :=3D V.Constant_Reference (X, 1); -- (C)
X(1).Re :=3D X(1).Re + 1.0; -- (D)
If the Copy function did not create any new copies of elements, then Ref1.E=
lement and Ref2.Element will end up being accesses to the same element, aft=
er (C) is performed. If the new copy of the element is not created until R=
eference is evaluated by the left side of statement (D), the result is that=
either Ref2.Element (or possibly Ref1.Element) will be pointing at the wro=
ng thing. =20
So it looks to me like the method you suggest shouldn't be allowed, even in=
your own container, since it would make it impossible to implement Constan=
My caveat still applies, though; this involves issues that I'm not yet comp=
letely familiar with, so it's possible that I made a serious error. I'm ho=
ping someone will come to my rescue if I did ... :)