comp.lang.ada
 help / color / mirror / Atom feed
From: "Marc A. Criley" <marc.a.criley@lmco.com>
Subject: Re: "recursive" accept statement ??
Date: 1998/12/15
Date: 1998-12-15T00:00:00+00:00	[thread overview]
Message-ID: <3676575E.C3DB1843@lmco.com> (raw)
In-Reply-To: 1998Dec15.122957@lri.fr

Frederic Voisin wrote:
> 
> I have trouble understanding the behavior of the following program (or
> the rationale
> for allowing its behavior, if correct):
> -------------------------------------
> with Ada.text_io ; use Ada.text_io ;
> 
> procedure Biz is
> 
> task trace is
>      entry put(str : string) ;
> end trace ;
> 
> task body trace is
> begin
>    accept Put (str : string) do
>           Ada.text_io.put(str);         -- works fine
>           Put(Str);                     -- behave like trace.Put(str) ????
>           New_Line;
>           end Put;
> end trace ;
> 
> begin Trace.Put("Hello World");
> end Biz;
> ---------------------------------------
> 
> When compiled with GNAT (gnat-3.10p on a Solaris machine) I get only the first
> 'Hello World" but not the second, while I would have expected the
> Put(str) within
> the "accept" statement to correspond to Ada.text_io.put and not to an
> implicit
> rendez-vous with the same task - as if I had written trace.put(str) -
> that is sure
> to deadlock !!

Deadlock is the expected behavior for this code.

> 
> Is that the right behavior (omitting the name of the called task,
> especially from
> within itself !) or is it a bug (I cannot test it with another compiler)
> ?
> If allowed, what is the rationale behind, since such construct is much
> error-proned
> (and I had a hard time finding it)
> Shouldn't it deserve a warning ?? or a complain about ambiguity ?

There's no ambiguity here.

This is simply a matter of scoping.  The entry declaration of Put:
   entry Put(str: String)
has a parameter profile identical to Text_IO's Put:
   procedure Put(Item : in  String)

Inside the accept block, the innermost entity having a name and
parameter profile matching "Put(str)" is the Put entry, therefore it
is recusively invoked and obviously deadlocks.

Identifiers in inner scopes hiding identical identifiers in outer
scopes is not uncommon, and issuing a warning whenever this occurs
would only rarely be of any utility.

Also, as a matter of general principle, since a task rendezvous blocks
both caller and callee while the accept block is executing, one usually
tries to make that rendezvous as brief as possible.  Here's a way of
doing that (which also eliminates the scoping/deadlock issue):

task body trace is
   S : string(1..Max_String_Length);
   L : Natural;  -- should be the 1..Max_String_Length subtype
begin
   accept Put (str : string) do
      S(str'range) := Str;
      L := S'Length;
   end Put;
   -- Caller is now released

   Ada.text_io.put(S(1..L));         -- works fine
   Put(S(1..L));                     -- Now outside of Put entry's scope
   New_Line;

end trace ;


> I did not find something really illuminating in the Reference Manual or
> Rationale...
> 
> Thanks

-- 
Marc A. Criley
Chief Software Architect
Lockheed Martin M&DS
marc.a.criley@lmco.com
Phone: (610) 354-7861
Fax  : (610) 354-7308




  parent reply	other threads:[~1998-12-15  0:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-12-15  0:00 "recursive" accept statement ?? Frederic Voisin
1998-12-15  0:00 ` David C. Hoos
1998-12-15  0:00 ` Tucker Taft
1998-12-15  0:00 ` dennison
1998-12-15  0:00   ` Matthew Heaney
1998-12-15  0:00 ` Marc A. Criley [this message]
1998-12-15  0:00   ` Matthew Heaney
1998-12-23  0:00 ` Robert A Duff
replies disabled

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