From: "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com>
Subject: Re: Who is right? Gnat or http://www.adahome.com/articles/1998-02/ar_lessons95.html?
Date: 1999/04/07
Date: 1999-04-07T00:00:00+00:00 [thread overview]
Message-ID: <5VxQ6WNg#GA.143@pet.hiwaay.net> (raw)
In-Reply-To: 01be80c2$114e0890$c24d3a8b@m04w0588
Daniel Wengelin wrote in message <01be80c2$114e0890$c24d3a8b@m04w0588>...
>
>
>When looking around for some infomration about OOP I came across the
>article http://www.adahome.com/articles/1998-02/ar_lessons95.html.
>
<large snip>
>I gave the code a try with Gnat 3.11 as follows.
>
>generic
> type Item_T is private;
>package List is
> type Node;
> type Object is access Node;
> type Node is record
> I : Item_T;
> Next:Object;
> end record;
>
> type Action_Proc is access procedure
> (I : in out Item_T);
> procedure Iterate
> (The_Action : Action_Proc;
> Through_List : Object);
>end List;
>
>---------------------------
>package body List is
> procedure Iterate
> (The_Action : Action_Proc;
> Through_List : Object)
> is
> Current : Object := Through_List;
> begin
> while Current /= null loop
> The_Action(Current.I);
> Current := Current.Next;
> end loop;
> end Iterate;
>end List;
>
>------------------------
>
>procedure List_Test is
>
> procedure Print (C: in out Character) is
> begin
> Ada.Text_Io.Put(C);
> Ada.Text_Io.New_Line;
> end Print;
> package C_List is new List(Character);
>
> The_List : C_List.Object := null;
>begin
> for I in Character range 'a' .. 'e' loop
> The_List := new C_List.Node'(I, The_List);
> end loop;
>
> C_List.Iterate (Print'Access, The_List);
>end List_Test;
>
>The above source compiled and ran without any problems. So, did I
>misunderstand or is Gnat wrong or is the article in AdaHome wrong?
>
Well, you must have an amazing version of gnat-3.11, for your code
won't compile either without the required context clauses for
Ada.Text_IO, and List in the List_Test source file ;).
But, seriously, I am glad to say Jean-Marie Dautelle is incorrect
in the article you cited.
Indeed I have used access to subprograms many times in multi-tasking
programs. The basic rule is that accesses to subprograms must
not have a lifetime greater than that of the subprogram.
So, in your example, even though the procedure Print only exists
during the execution of procedure List_Test, there is no problem
because the lifetime of Print cannot be less than that of the
access type C_List.Action_Proc;
Frequently, all this limitation means is that the subprogram must
be declared at library level -- i.e. such that the lifetime of
the subprogram is the same as that of the main program.
For example, if you make this small change to your code (leaving
the generic List package unchanged, the program will not compile:
----
with List;
package C_List is new List(Character);
----
with Ada.Text_IO;
with C_List;
procedure List_Test is
procedure Print (C: in out Character) is
begin
Ada.Text_IO.Put(C);
Ada.Text_IO.New_Line;
end Print;
The_List : C_List.Object := null;
begin
for I in Character range 'a' .. 'e' loop
The_List := new C_List.Node'(I, The_List);
end loop;
C_List.Iterate (Print'Access, The_List);
end List_Test;
----
In this case, the access type C_List.Action_Proc could have a
lifetime greater than that of the subprogram Print. When gcc
compiles List_Test, it has no way of knowing that List_Test
is the main program, so the compilation fails. As the RM
puts it, the subprogram access level is deeper than that of
the access type, which is not allowed.
But what if the generic instantiation C_List is to be used
by more than one compilation unit, and therefore must be
declared at library level? Again, another small change makes
things well again.
with List;
package C_List is new List(Character);
----
with Ada.Text_IO;
procedure Print (C: in out Character) is
begin
Ada.Text_IO.Put(C);
Ada.Text_IO.New_Line;
end Print;
----
with C_List;
with Print;
procedure List_Test is
The_List : C_List.Object := null;
begin
for I in Character range 'a' .. 'e' loop
The_List := new C_List.Node'(I, The_List);
end loop;
C_List.Iterate (Print'Access, The_List);
end List_Test;
----
Now, once again, the lifetime of Print is at least as long
as that of the access type C_List.Action_Proc.
next prev parent reply other threads:[~1999-04-07 0:00 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
1999-04-07 0:00 Who is right? Gnat or http://www.adahome.com/articles/1998-02/ar_lessons95.html? Daniel Wengelin
1999-04-07 0:00 ` Robert Dewar
1999-04-07 0:00 ` David C. Hoos, Sr. [this message]
1999-04-07 0:00 ` Daniel Wengelin
1999-04-07 0:00 ` Tucker Taft
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox