comp.lang.ada
 help / color / mirror / Atom feed
* Thanks Tucker, It works !!!
@ 1998-09-19  0:00 Technobabble
  1998-09-20  0:00 ` dewarr
  0 siblings, 1 reply; 4+ messages in thread
From: Technobabble @ 1998-09-19  0:00 UTC (permalink / raw)


Greetings,

The final code, which I compiled with GNAT, outputs the following:

test_pkg
test_pkg
test_pkg
test_pkg
test_pkg

Basically, I wanted to specify an unconstrained array in a spec for a user
and then let the user constrain it.  Then a procedure, also in the spec,
could determine the size of the array, in this case 5, since the loop
executed 5 times. But I had to do it with an access type per design
requirements.

Below is the final code, I still don't really understand the aliased, all,
and access keywords working together to allow this sort of C-like pointer
operation, but Ada95 does allow it.  Anyone care to explain, I'd love to
learn the reasons behind allowing pointer operations.

Question:  would this work in Ada83 not having these keywords???


Here is the final code:



****
file test_pkg.ads
****
package test_pkg is

 type xyz_array is array (integer range <>) of integer;   -- this is it

 type xyz_array_pointer is access all xyz_array;

 type xyz_array_pointer_array is array (1..100) of xyz_array_pointer;


 type Object is
     record
        XYZ : xyz_array_pointer_array;    
        abc : integer;
     end record;

 -- user can define this array externally, just here for demo
 xyz5_array : aliased xyz_array := (1..5 => 0);

 procedure my_range (This : in out Object); 

end test_pkg;



****
file: my_main.adb
****
with test_pkg; use test_pkg;
procedure my_main is
   my_this : Object;
begin
   my_range (my_this);
end my_main;



****
file: test_pkg.adb
****

with Text_IO; use Text_IO;
package body test_pkg is

procedure my_range (This : in out Object) is
begin 
        -- next line can be externally done by user, here for demo
        This.XYZ(1) := xyz5_array'ACCESS;  -- address of xyz5_array is assigned
        for I in This.XYZ(1)'RANGE
        loop
          put_line ("test_pkg");
        end loop;

end my_range;

end test_pkg;




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

* Re: Thanks Tucker, It works !!!
  1998-09-19  0:00 Thanks Tucker, It works !!! Technobabble
@ 1998-09-20  0:00 ` dewarr
  1998-09-20  0:00   ` Technobabble
  0 siblings, 1 reply; 4+ messages in thread
From: dewarr @ 1998-09-20  0:00 UTC (permalink / raw)


In article <WishList-1909981556420001@a2.phoenix-9.goodnet.com>,
  WishList@2600.com (Technobabble) wrote:
> Greetings,
>
> The final code, which I compiled with GNAT, outputs the following:
>
> test_pkg
> test_pkg
> test_pkg
> test_pkg
> test_pkg
>
> Basically, I wanted to specify an unconstrained array in a spec for a user
> and then let the user constrain it.  Then a procedure, also in the spec,
> could determine the size of the array, in this case 5, since the loop
> executed 5 times. But I had to do it with an access type per design
> requirements.
>
> Below is the final code, I still don't really understand the aliased, all,
> and access keywords working together to allow this sort of C-like pointer
> operation, but Ada95 does allow it.  Anyone care to explain, I'd love to
> learn the reasons behind allowing pointer operations.
>
> Question:  would this work in Ada83 not having these keywords???
>
> Here is the final code:
>
> ****
> file test_pkg.ads
> ****
> package test_pkg is
>
>  type xyz_array is array (integer range <>) of integer;   -- this is it
>
>  type xyz_array_pointer is access all xyz_array;
>
>  type xyz_array_pointer_array is array (1..100) of xyz_array_pointer;
>
>  type Object is
>      record
>         XYZ : xyz_array_pointer_array;
>         abc : integer;
>      end record;
>
>  -- user can define this array externally, just here for demo
>  xyz5_array : aliased xyz_array := (1..5 => 0);
>
>  procedure my_range (This : in out Object);
>
> end test_pkg;
>
> ****
> file: my_main.adb
> ****
> with test_pkg; use test_pkg;
> procedure my_main is
>    my_this : Object;
> begin
>    my_range (my_this);
> end my_main;
>
> ****
> file: test_pkg.adb
> ****
>
> with Text_IO; use Text_IO;
> package body test_pkg is
>
> procedure my_range (This : in out Object) is
> begin
>         -- next line can be externally done by user, here for demo
>         This.XYZ(1) := xyz5_array'ACCESS;  -- address of xyz5_array is
assigned
>         for I in This.XYZ(1)'RANGE
>         loop
>           put_line ("test_pkg");
>         end loop;
>
> end my_range;
>
> end test_pkg;
>




Yes, well of course this code works, but you should never
write code you don't fully understand! It is of course
trivial to remove the gratuitous use of access in a program
like this, and it is almost certainly the case that in the
"real" code, there is also no good reason for using access.

No, of course this code will not work in Ada 83. One could
perhaps push it into working by using
'Address and unchecked conversion and hoping that the
compiler will be friendly enough for this to work (there
is no guarantee that it would).

THe introduction of aliased and the access attribute into
Ada 95 was always a controversial one. This kind of low
level pointer messing was excluded from Ada 83 for very
good reasons. It was introduced in Ada 95 for very narrow
uses. Historically, the argument that overcame many people's
great uneasiness with this feature was the need for creating
statically initialized data structures containing pointers.

Once there, the feature also has some other legitimate uses,
but I think it tends to cause more trouble than it is worth.
For example, people are often getting into trouble trying to
model external C routines by using access parameters instead
of pointer parameters. This is almost wrong because of the
(perfectly reasonable if you have the right view of things)
viewpoint that an access parameter should never be null.

Access parameters the use of 'Access also appear in the case
of function arguments to get around the (extraordinarily
idiotic) rule that functions cannot take in/out parameters.
Here is a case where the language design is simply flawed,
and so people have to get around it (try coding up the
random number packages IN THE RM sometime in Ada!)

The huge disadvantage of adding a feature like this to the
language is precisely the kind of bad code quoted here. This
code can perfectly well be written without using access (and
the rewrite is a trivial excercise). The appeal to legacy
code is very dubious, seeing as you couldn't do this in
properly written Ada 83 anyway, and if you are dealing with
junk Ada 83 code using unchecked conversion, then it might
as well be converted unchanged.

Still the feature is there. If you want to use it, you should
most certainly understand what you are doing. The use of
the aliased keyword in particular is important.

Everyone agrees that in general terms aliasing is bad. One
of the very unattractive features of a language like C is
that everything can be aliased in an arbitrary manner. The
use of 'Access in Ada 95 allows an increase in aliasing, but
we still try to control it. You can only create pointers to
variables if they have the aliased keyword. Clearly any
coding standard for Ada 95 should have the same kind of
allergy for the use of the aliased keyword that it has for
other features that are to be used only when absolutely
necessary.

Code with aliased keywords all over the place is flawed in
the same way as code with unchecked conversion all over the
place. That does not mean that neither feature should never
be used, but it means that gratuitous use, as in the above
program, is to be avoided where possible.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




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

* Re: Thanks Tucker, It works !!!
  1998-09-20  0:00 ` dewarr
@ 1998-09-20  0:00   ` Technobabble
  0 siblings, 0 replies; 4+ messages in thread
From: Technobabble @ 1998-09-20  0:00 UTC (permalink / raw)



> Yes, well of course this code works, but you should never
> write code you don't fully understand!

agreed, I'm working on learning it.

> It is of course
> trivial to remove the gratuitous use of access in a program
> like this, and it is almost certainly the case that in the
> "real" code, there is also no good reason for using access.
> 
> No, of course this code will not work in Ada 83. One could
> perhaps push it into working by using
> 'Address and unchecked conversion and hoping that the
> compiler will be friendly enough for this to work (there
> is no guarantee that it would).

Consider a user of the package test_pkg:

with test_pkg;

proceder User_proc is
   My_This is new This;
begin

  xyz5_array : aliased This.xyz_array := (1..5 => 0);
  This.XYZ(1) := xyz5_array'ACCESS;

the user then calls my_range:

  This.my_range (My_This);
end User_proc;


Ok, since I really missed the point about stack versus heap allocation, as
far as I know the user will be using static heap allocation and my own
poor communticatin of this problem has led me to the issue of aliased
pointers. So from the previous post could I do this? :

with test_pkg;

proceder User_proc is
   My_This is new This;
   xyz5_array is new This.xyz_array'((1..5 => 0));
begin

  This.XYZ(1) := This.xyz_array'((1..5 => 0));

the user then calls my_range:

  my_range (My_This);
end User_proc;

I'll compile it and see. I started this way but had problems understanding
the issue of assignment of an access type to unconstrained versus the
constrained side of the equation, hence the late night psycho bable, bad
syntax, and massive  confusion. Thanks for your patience. Maybe I don't
need the aliased approach at all.
 
> THe introduction of aliased and the access attribute into
> Ada 95 was always a controversial one. This kind of low
> level pointer messing was excluded from Ada 83 for very
> good reasons. It was introduced in Ada 95 for very narrow
> uses. Historically, the argument that overcame many people's
> great uneasiness with this feature was the need for creating
> statically initialized data structures containing pointers.
> 
> Once there, the feature also has some other legitimate uses,
> but I think it tends to cause more trouble than it is worth.
> For example, people are often getting into trouble trying to
> model external C routines by using access parameters instead
> of pointer parameters. This is almost wrong because of the
> (perfectly reasonable if you have the right view of things)
> viewpoint that an access parameter should never be null.

smart.  Thanks for the info, I'll save this letter.

> Access parameters the use of 'Access also appear in the case
> of function arguments to get around the (extraordinarily
> idiotic) rule that functions cannot take in/out parameters.
> Here is a case where the language design is simply flawed,
> and so people have to get around it (try coding up the
> random number packages IN THE RM sometime in Ada!)
> 
> The huge disadvantage of adding a feature like this to the
> language is precisely the kind of bad code quoted here. This
> code can perfectly well be written without using access (and
> the rewrite is a trivial excercise). The appeal to legacy
> code is very dubious, seeing as you couldn't do this in
> properly written Ada 83 anyway, and if you are dealing with
> junk Ada 83 code using unchecked conversion, then it might
> as well be converted unchanged.

Great explaination!  The legacy code is a  C/Ada bus driver, I'm
converting everything to Ada95 (they told me that they'd get me into an
Ada95 training class...soon I hope).

> Still the feature is there. If you want to use it, you should
> most certainly understand what you are doing.

I'd prefer not to use it and to simplify my code fragment along the lines
given above if I can do it of course.

> The example is a Patriot missile to shoot down a fly.  One trusts
> there's a reason for this complexity in the actual app.
That's really funny. The design was originally done by a pointer crazed C coder.

Thanks for the excellent resopnse !!!
Richmond




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

* Re: Thanks Tucker, It works !!!
@ 1998-09-20  0:00 tmoran
  0 siblings, 0 replies; 4+ messages in thread
From: tmoran @ 1998-09-20  0:00 UTC (permalink / raw)


> But I had to do it with an access type per design requirements.
The example is a Patriot missile to shoot down a fly.  One trusts
there's a reason for this complexity in the actual app.

> I still don't really understand the aliased, all, and access
> keywords working together to allow this sort of C-like pointer
Here's one attempt at an explanation:

  Your Object contains, among other things (eg, abc) a set of 100
pointers to variable sized arrays of integers.  These arrays are not
created dynamically by 'new' allocators, but are in fact aliases of
ordinary arrays declared statically (eg xyz5_array), thus allowing
'back door' access to those arrays and the resulting maintenance,
optimization, storage/register placement etc problems of things that
can be read or written directly (xyz5_array(3) := 17;) or indirectly
(This.XYZ(1).all(3) := 17;).  The key word 'aliased' gives warning to
the compiler and the maintainer that such shenanigans are going on
with xyz5_array.

  Usually, access types point to things dynamically allocated on the
heap with 'new'.  But your type "xyz_array_pointer" may in fact point
to something allocated on the stack, like xyz5_array, as well.  The
keyword 'all' tells the compiler and the maintainer this vital fact
about xyz_array_pointer.

  An Ada 83 access type only pointed to heap-allocated objects, so it
didn't have 'all' or 'aliased'.  Basically, to make your program run
in Ada 83, you would have to simplify it by dropping those key words
and the line
  xyz5_array : aliased xyz_array := (1..5 => 0);
and changing
  This.XYZ(1) := xyz5_array'ACCESS;  -- address of xyz5_array is assigned
to
  This.XYZ(1) := new xyz_array'((1..5 => 0)); -- an xyz5 array is created

  Your next question, should you choose to continue this task, will
probably be about the error messages you get when forgetting about the
lifetime problems of pointers to things that disappear when the stack
is popped on return from a subprogram.




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

end of thread, other threads:[~1998-09-20  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-09-19  0:00 Thanks Tucker, It works !!! Technobabble
1998-09-20  0:00 ` dewarr
1998-09-20  0:00   ` Technobabble
  -- strict thread matches above, loose matches on Subject: below --
1998-09-20  0:00 tmoran

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