From: Matthew Heaney <matthew_heaney@acm.org>
Subject: Re: "out" or "access"
Date: 1998/10/30
Date: 1998-10-30T00:00:00+00:00 [thread overview]
Message-ID: <m3zpaeqq56.fsf@mheaney.ni.net> (raw)
In-Reply-To: 71cjab$ka8$1@nnrp1.dejanews.com
dennison@telepath.com writes:
> In article <wcc3e87hrl8.fsf@world.std.com>,
> Robert A Duff <bobduff@world.std.com> wrote:
>
>> But how about this workaround: declare New_Iterator to take an 'in'
>> parameter of type Root_Queue. (Presuming you really do want an
>> iterator that can't modify the thing it's iterating over.) So it's
>> dispatching, which you want. Inside the various overridings of it,
>> you will normally have to do 'Unchecked_Access to produce a pointer
>> to the thing, which
>
> I must be missing something here. Isn't it possible that taking an
> 'Unchecked_Access of an in parameter will just give you a pointer to a
> copy of the object on the stack, which will disappear when the
> procedure ends? Or are you saying to do a ".all'Unchecked_Access" on
> the in parameter?
We're talking about tagged types here, and there are special rules that
apply to objects of a tagged type.
The RM mandates that tagged types be passed by reference, and so tagged
types passed as subprogram arguments are "implicitly aliased." That's
why you can say:
procedure Op (O : in T) is -- T is a tagged type
type TA is access constant T;
OA : constant TA := O'Access;
begin
without O being declared as "access T" --because T is tagged. Ditto for
procedure Op (O : in out T) is
type TA is access all T;
OA : constant TA := O'Access;
begin
The RM also recommends that implementations "deliver a useful result"
when you take the O'Address of a by-reference type (tagged types,
limited types) passed as a subprogram parameter. That's why
Sys.Addr_To_Acc_Conv can be used to work around this problem.
You don't ever have to pass tagged types as access parameters --unless
you need the operation to dispatch.
My problem is I need to do this:
procedure Visit (S : Stack'Class) is
I : Iterator'Class := Initialize (S'Access);
begin
where Initialize is a function that takes a _constant_ access parameter
and returns an iterator (whose type is class-wide).
The problem is ... I can't do that, because access constant parameters
don't exist in the language.
The workaround is to pass the argument as an in param --not access
constant param-- so it will dispatch, then use Addr_To_Acc_Conv to turn
that into a useful pointer:
function Initialize (S : Stack) return Iterator'Class;
This func is primitive for type Stack, and therefore it dispatches:
package Stacks.My_Stacks is
type My_Stack is new Stack with private;
type My_Iterator is new Iterator with private;
function Initialize (S : My_Stack) return Iterator'Class;
...
private
...
package Conv is new Sys.Addr_To_Acc_Conv (My_Stack);
type My_Iterator is
new Iterator with record
Stack : Conv.Object_Pointer;
Index : <some index type>;
end record;
function Initialize (S : My_Stack) return Iterator'Class is
begin
return My_Iterator'(To_Pointer (S'Address), S.Top);
end;
So now the iterator object contains a pointer to the stack object passed
in. The works --and I'm not unhappy with it-- it's just that there's no
way to prevent dangling references, as you can with access parameters.
The declaration
procedure Print (S : Stack'Class) is
Iter : Iterator'Class := Start_At_Top (S);
begin
doesn't make it obvious that the _address_ of S is being looked at, and
that object Iter contains a pointer to S. That's why it's important to
make sure that the stack object lives at least as long as the iterator,
or else a dangling reference will occur.
I'd much rather say
procedure Print (S : Stack'Class) is
Iter : Iterator'Class := Start_At_Top (S'Access);
begin
because it states explicitly that I'm manipulating a reference, but I
can't do that, because the language doesn't allow it.
So although technically speaking you don't _need_ access constant
parameters --because an in param dispatches, and you can sensibly take
the address of a tagged type passed as a param-- having access constant
parameters is still _strongly_ desireable.
It frustrates me that you can't implement a factory method for an
iterator, without having to use back-door methods.
next prev parent reply other threads:[~1998-10-30 0:00 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
1998-10-21 0:00 "out" or "access" =:-) Vincent
1998-10-21 0:00 ` Jeff Carter
1998-10-21 0:00 ` Pat Rogers
1998-10-21 0:00 ` Martin C. Carlisle
1998-10-22 0:00 ` Pat Rogers
1998-10-22 0:00 ` Robert A Duff
1998-10-21 0:00 ` dennison
1998-10-21 0:00 ` Tucker Taft
1998-10-22 0:00 ` Pascal Obry
1998-10-29 0:00 ` Robert A Duff
1998-10-29 0:00 ` Matthew Heaney
1998-10-29 0:00 ` Robert A Duff
1998-10-30 0:00 ` dennison
1998-10-30 0:00 ` Matthew Heaney [this message]
1998-10-30 0:00 ` Robert A Duff
1998-10-31 0:00 ` Matthew Heaney
1998-11-01 0:00 ` Robert A Duff
1998-11-01 0:00 ` Matthew Heaney
1998-11-01 0:00 ` Robert A Duff
1998-11-02 0:00 ` Matthew Heaney
1998-11-03 0:00 ` Simon Wright
1998-11-16 0:00 ` Matthew Heaney
1998-10-31 0:00 ` dewar
1998-10-31 0:00 ` Matthew Heaney
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox