comp.lang.ada
 help / color / mirror / Atom feed
* Access to tagged type parameters
@ 2001-08-17  9:16 Jonathan DeSena
  2001-08-17 16:23 ` David Brown
  2001-08-17 21:45 ` tmoran
  0 siblings, 2 replies; 7+ messages in thread
From: Jonathan DeSena @ 2001-08-17  9:16 UTC (permalink / raw)


According to Cohen's "Ada as a Second Language," which I've been using to 
pick up Ada95 in my spare time:

"All formal parameters belonging to tagged 
types are implicitly declared to be aliased. This allows a subprogram to 
create access values pointing to its tagged formal parameters using the 
'Access attribute ..." (section 12.6.2, page 579 in my version)

This is the ONLY reference to this in the book I can find; there are no 
examples of it's use, though it seems simple enough.  However, no matter 
what I try, I can't seem to get such code to compile using gnat 3.13p on 
Debian/Linux (Intel). I continually get the following error:

non-local pointer cannot point to local object

Here's a code snippet which I've been using as a test case -- it doesn't do 
anything, but I just use it to see if it will compile:
--start test.adb
with Ada.Text_IO;
procedure Test is

   type A_Type is tagged record
      A1:Integer; --just to fill the record with something
      A2:Integer;
   end record;
   type A_Access_type is access all A_Type'Class;

   procedure A_Test (B:in out A_Type'Class) is
      B_Access: A_Access_Type;
   begin
      B_Access:=B'Access;
      Ada.Text_IO.Put_Line("Done.");
   end A_Test;

   C:A_Type;
begin
   A_Test(C);
end Test;
--end test.adb

Does anyone know if this works as advertised? Or maybe I am 
misunderstanding the statement in the book? Anyone have a similar example 
to the above that DOES work?

I'd like to be able to use access values to a tagged type in a subprogram 
which has the type itself as a parameter rather than an access type. That 
way, when the tagged type is inherited, the subprograms will go with it. 
Subprograms which only have access types to the tagged type do not get 
inhereted by the derived type it seems.

Thanks in advance.

jtd



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to tagged type parameters
  2001-08-17 19:26   ` Ted Dennison
@ 2001-08-17 13:55     ` Jonathan DeSena
  2001-08-17 21:51       ` Ted Dennison
  0 siblings, 1 reply; 7+ messages in thread
From: Jonathan DeSena @ 2001-08-17 13:55 UTC (permalink / raw)


Ted Dennison wrote:

> In article <pybf7.17453$ZM2.1548231@newsread2.prod.itd.earthlink.net>,
> David Brown says...
>>
>>Jonathan DeSena <jonathan.desena@jhuapl.edu> wrote:
>>
>>> "All formal parameters belonging to tagged
>>> types are implicitly declared to be aliased. This allows a subprogram to
>>> create access values pointing to its tagged formal parameters using the
>>> 'Access attribute ..." (section 12.6.2, page 579 in my version)
>>> 
>>> non-local pointer cannot point to local object
>>
>>>      B_Access: A_Access_Type;
>>
>>The pointer access type A_Access_Type has a scope outside of the scope of
>>the object you getting the access value of.
> 
> Actually, it doesn't though. The actual pointed-to object is B, which is
> declared at the same scope as A_Access_Type.
> 
> It looks like the compiler is considering C (the formal parameter) to be
> the pointed to object instead of B (the actual parameter). I guess it can
> do that, but then I don't much see the point of the rule specifying that
> tagged types are always passed by reference. By this rule a tagged
> by-value pointer would be just as safe (and useful). I guess it still has
> use for 'Unchecked_Access...
> 
> FWIW, GreenHills tags the same line with the following error:
> LRM:3.10.2(28), The prefix to 'ACCESS shall not be statically deeper than
> that of the expected type, Continuing
> 
So, does that mean the original quote is incorrect, or just that some 
compilers do not impliment it correctly? 

>>If you use 'Unchecked_Access,
>>you will get the access you want, however, the it is up to you to make
>>sure it doesn't go outside of scope.
> 
> Another possibility is to use the "access" parameter mode instead of "in
> out". In that case, the accessability rules seem to behave as I would
> expect.
Unfortunately, the reason I want to do this is to be able to add the passed 
in tagged type, say type A_Type, to a routine which will add it's access 
value to an array of access values, say  A_Access_Type.  Thus I WANT to be 
able to do the equivalent of the assignment B_Access := B'Access. If B is 
type access to A_Type'Class, I cannot do B_Access:=B, or something. On the 
otherhand, if I use the type A_Access_Type as the paramater instead, the 
assignment B_Access:=B works (since B & B_Access are now the same type), 
but the routine is not inhereted to derived types of A_Type. This means 
that it is very difficult to use tagged types AND access types together and 
still take advantage of inheritance. (Does that paragraph make any sense, 
or do I need to clarify? It now seems unwieldy to me. Oh well) 

I suppose 'Unchecked_Access might do the trick, but I don't know enough to 
know where the pitfalls of using it are. Also, this seems overly 
complicated just because of using a tagged type.

I tried to remove as many access types as possible to simplify matters, but 
because I am using a recursive type, they are required (won't compile 
without them).  Because of Ada's strong typing (a good thing, I agree), 
once I use access types, they seem to proliferate throughout the package.

Thanks again,
jtd
  




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to tagged type parameters
  2001-08-17  9:16 Access to tagged type parameters Jonathan DeSena
@ 2001-08-17 16:23 ` David Brown
  2001-08-17 19:26   ` Ted Dennison
  2001-08-17 21:45 ` tmoran
  1 sibling, 1 reply; 7+ messages in thread
From: David Brown @ 2001-08-17 16:23 UTC (permalink / raw)


Jonathan DeSena <jonathan.desena@jhuapl.edu> wrote:

> "All formal parameters belonging to tagged 
> types are implicitly declared to be aliased. This allows a subprogram to 
> create access values pointing to its tagged formal parameters using the 
> 'Access attribute ..." (section 12.6.2, page 579 in my version)
> 
> non-local pointer cannot point to local object

>      B_Access: A_Access_Type;

The pointer access type A_Access_Type has a scope outside of the scope of
the object you getting the access value of.  If you use 'Unchecked_Access,
you will get the access you want, however, the it is up to you to make sure
it doesn't go outside of scope.

This access can easily be used to call procedures/functions that take
access parameters.  Since access parameters cannot be assigned (without
conversions) to access types, the object can only be accessed within that
procedure/function.

Here is your example modified to use an access type:

-------------------------
with Ada.Text_IO;
procedure Test is

   type A_Type is tagged record
      A1:Integer; --just to fill the record with something
      A2:Integer;
   end record;
   type A_Access_type is access all A_Type'Class;

   procedure Access_Arg (AC : access A_Type'Class) is
   begin
      null;
   end Access_Arg;

   procedure A_Test (B:in out A_Type'Class) is
   begin
      Access_Arg (B'Access);
      Ada.Text_IO.Put_Line("Done.");
   end A_Test;

   C:A_Type;
begin
   A_Test(C);
end Test;
-------------------------

--
David Brown



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to tagged type parameters
  2001-08-17 16:23 ` David Brown
@ 2001-08-17 19:26   ` Ted Dennison
  2001-08-17 13:55     ` Jonathan DeSena
  0 siblings, 1 reply; 7+ messages in thread
From: Ted Dennison @ 2001-08-17 19:26 UTC (permalink / raw)


In article <pybf7.17453$ZM2.1548231@newsread2.prod.itd.earthlink.net>, David
Brown says...
>
>Jonathan DeSena <jonathan.desena@jhuapl.edu> wrote:
>
>> "All formal parameters belonging to tagged 
>> types are implicitly declared to be aliased. This allows a subprogram to 
>> create access values pointing to its tagged formal parameters using the 
>> 'Access attribute ..." (section 12.6.2, page 579 in my version)
>> 
>> non-local pointer cannot point to local object
>
>>      B_Access: A_Access_Type;
>
>The pointer access type A_Access_Type has a scope outside of the scope of
>the object you getting the access value of.  

Actually, it doesn't though. The actual pointed-to object is B, which is
declared at the same scope as A_Access_Type.

It looks like the compiler is considering C (the formal parameter) to be the
pointed to object instead of B (the actual parameter). I guess it can do that,
but then I don't much see the point of the rule specifying that tagged types are
always passed by reference. By this rule a tagged by-value pointer would be just
as safe (and useful). I guess it still has use for 'Unchecked_Access...

FWIW, GreenHills tags the same line with the following error:
LRM:3.10.2(28), The prefix to 'ACCESS shall not be statically deeper than that
of the expected type, Continuing

>If you use 'Unchecked_Access,
>you will get the access you want, however, the it is up to you to make sure
>it doesn't go outside of scope.

Another possibility is to use the "access" parameter mode instead of "in out".
In that case, the accessability rules seem to behave as I would expect.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to tagged type parameters
  2001-08-17  9:16 Access to tagged type parameters Jonathan DeSena
  2001-08-17 16:23 ` David Brown
@ 2001-08-17 21:45 ` tmoran
  1 sibling, 0 replies; 7+ messages in thread
From: tmoran @ 2001-08-17 21:45 UTC (permalink / raw)


>I'd like to be able to use access values to a tagged type in a subprogram
>which has the type itself as a parameter rather than an access type. That
>way, when the tagged type is inherited, the subprograms will go with it.
>Subprograms which only have access types to the tagged type do not get
>inhereted by the derived type it seems.
  "A subprogram declared ... is a primitive operation of that type if
it has a parameter of type T, an access parameter pointing to objects
of type T, ..."  Ada as a language, bottom of p. 504

>non-local pointer cannot point to local object
  Consider:

   type A_Type is tagged record ...
   type A_Access_type is access all A_Type'Class;

   Outer_B : A_Access_Type;

   procedure A_Test (B:in out A_Type'Class) is
      B_Access: A_Access_Type;
   begin
      B_Access:=B'Access;
      Outer_B := B_Access;
      Ada.Text_IO.Put_Line("Done.");
   end A_Test;

   procedure Test is
     X : A_Type;
   begin
     A_Test(X);
   end Test;
begin
   Test;
   Outer_B.all := ....     -- what does this point to???

A local object, X, disappears while a non-local pointer, Outer_B, is
still pointing to it.  You need to make "type A_Access_Type" more
local so any such pointer will be guaranteed to disappear no later
than anything it points to.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to tagged type parameters
  2001-08-17 13:55     ` Jonathan DeSena
@ 2001-08-17 21:51       ` Ted Dennison
  2001-08-20 14:03         ` Jonathan DeSena
  0 siblings, 1 reply; 7+ messages in thread
From: Ted Dennison @ 2001-08-17 21:51 UTC (permalink / raw)


In article <9ljud5$ck8$1@houston.jhuapl.edu>, Jonathan DeSena says...
>
>Ted Dennison wrote:
>> FWIW, GreenHills tags the same line with the following error:
>> LRM:3.10.2(28), The prefix to 'ACCESS shall not be statically deeper than
>> that of the expected type, Continuing
>> 
>So, does that mean the original quote is incorrect, or just that some 
>compilers do not impliment it correctly? 

I think the Gnat compiler is catching the same error for the same reason, but is
attempting to give it a short understandable message, rather than refer you to
one of the most obtuse sections of the LRM.

What I'm not sure about is *why* this is illegal, but if two compilers based on
two very different front ends flag it, I suspect it is a perfectly valid error.
Hopefully a good language-lawyer can come and explain it for us...

>> Another possibility is to use the "access" parameter mode instead of "in
>> out". In that case, the accessability rules seem to behave as I would
>> expect.
>Unfortunately, the reason I want to do this is to be able to add the passed 
>in tagged type, say type A_Type, to a routine which will add it's access 
>value to an array of access values, say  A_Access_Type.  Thus I WANT to be 

That's fine. You'd just change the parameter type to "access", the assignment to
"B_Access := A_Access_Type(B);", the procedure call to "A_Test(C'Access);", and
add an "aliased" to the declaration of B. I tried that with Gnat and it compiled
and ran successfully.

>I suppose 'Unchecked_Access might do the trick, but I don't know enough to 
>know where the pitfalls of using it are. Also, this seems overly 
>complicated just because of using a tagged type.

Since its totally unchecked, the pitfals are the ones you were willing to accept
when you tried to do the assignment in the first place: There is no guarantee
that the object that it points to will exist, unless you have structured your
code in such a way as to ensure it. If you find that you need Unchecked_Access,
you should certianly take a step back and see if that is the case. But you
shouldn't shy away from using it entirely, any more than a C user would shy away
from using "&" entirely. Sometimes it is nessecary. 

>I tried to remove as many access types as possible to simplify matters, but 
>because I am using a recursive type, they are required (won't compile 
>without them).  Because of Ada's strong typing (a good thing, I agree), 
>once I use access types, they seem to proliferate throughout the package.

If you want to create hetrogenious data structures for dynamic disptaching, they
are required. That's kind of an unfortunate departure from Ada's philosophy of
never requiring pointers, but there it is.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to tagged type parameters
  2001-08-17 21:51       ` Ted Dennison
@ 2001-08-20 14:03         ` Jonathan DeSena
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan DeSena @ 2001-08-20 14:03 UTC (permalink / raw)


Ted Dennison wrote:

> In article <9ljud5$ck8$1@houston.jhuapl.edu>, Jonathan DeSena says...
>>
>>Ted Dennison wrote:
>>> FWIW, GreenHills tags the same line with the following error:
>>> LRM:3.10.2(28), The prefix to 'ACCESS shall not be statically deeper
>>> than that of the expected type, Continuing
>>> 
>>So, does that mean the original quote is incorrect, or just that some
>>compilers do not impliment it correctly?
> 
> I think the Gnat compiler is catching the same error for the same reason,
> but is attempting to give it a short understandable message, rather than
> refer you to one of the most obtuse sections of the LRM.
> 
> What I'm not sure about is *why* this is illegal, but if two compilers
> based on two very different front ends flag it, I suspect it is a
> perfectly valid error. Hopefully a good language-lawyer can come and
> explain it for us...
> 
>>> Another possibility is to use the "access" parameter mode instead of "in
>>> out". In that case, the accessability rules seem to behave as I would
>>> expect.
>>Unfortunately, the reason I want to do this is to be able to add the
>>passed in tagged type, say type A_Type, to a routine which will add it's
>>access
>>value to an array of access values, say  A_Access_Type.  Thus I WANT to be
> 
> That's fine. You'd just change the parameter type to "access", the
> assignment to "B_Access := A_Access_Type(B);", the procedure call to
> "A_Test(C'Access);", and add an "aliased" to the declaration of B. I tried
> that with Gnat and it compiled and ran successfully.

Ahhh. This does what I want. I had forgotten about type conversions. 
Actually, it is interesting that you can pass an argument of type 
A_Access_Type to a subprogram expecting "access to A_Type," but  the 
converse is illegal; also, you can't equate or assign two variables of 
these two types. 

> 
>>I suppose 'Unchecked_Access might do the trick, but I don't know enough to
>>know where the pitfalls of using it are. Also, this seems overly
>>complicated just because of using a tagged type.
> 
> Since its totally unchecked, the pitfals are the ones you were willing to
> accept when you tried to do the assignment in the first place: There is no
> guarantee that the object that it points to will exist, unless you have
> structured your code in such a way as to ensure it. If you find that you
> need Unchecked_Access, you should certianly take a step back and see if
> that is the case. But you shouldn't shy away from using it entirely, any
> more than a C user would shy away from using "&" entirely. Sometimes it is
> nessecary.
> 
>>I tried to remove as many access types as possible to simplify matters,
>>but because I am using a recursive type, they are required (won't compile
>>without them).  Because of Ada's strong typing (a good thing, I agree),
>>once I use access types, they seem to proliferate throughout the package.
> 
> If you want to create hetrogenious data structures for dynamic
> disptaching, they are required. That's kind of an unfortunate departure
> from Ada's philosophy of never requiring pointers, but there it is.
>

Thanks to all. I was getting very frustrated, but I am better now :)

jtd



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2001-08-20 14:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-17  9:16 Access to tagged type parameters Jonathan DeSena
2001-08-17 16:23 ` David Brown
2001-08-17 19:26   ` Ted Dennison
2001-08-17 13:55     ` Jonathan DeSena
2001-08-17 21:51       ` Ted Dennison
2001-08-20 14:03         ` Jonathan DeSena
2001-08-17 21:45 ` tmoran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox