comp.lang.ada
 help / color / mirror / Atom feed
From: Alex Mentis <asmentis@gmail.com>
Subject: Re: Ensuring postconditions in the face of exceptions
Date: Sun, 14 Mar 2010 08:12:44 -0700 (PDT)
Date: 2010-03-14T08:12:44-07:00	[thread overview]
Message-ID: <5f3f45c6-0202-4a67-8517-182afaf7dceb@c16g2000yqd.googlegroups.com> (raw)
In-Reply-To: 87ljdv56gy.fsf@ludovic-brenta.org

On Mar 14, 10:21 am, Ludovic Brenta <ludo...@ludovic-brenta.org>
wrote:
> Alex Mentis writes:
> > On Mar 12, 4:13 am, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> >> Consider the procedure:
>
> >> type T is private; -- completion elided
>
> >> generic
> >>    with procedure Visit (Object : in out T);
> >> procedure Refresh (Object : in out T; Dirty : in out T) is
> >> begin
> >>    if Dirty then
> >>       Visit (Object);
> >>       Dirty := False;
> >>    end if;
> >> exception
> >>    when others =>
> >>       Dirty := True; -- warnings here
> >>       raise;
> >> end Refresh;
>
> >> GNAT says:
> >> warning: assignment to pass-by-copy formal may have no effect
> >> warning: "raise" statement may result in abnormal return (RM
> >> 6.4.1(17))
>
> >> The reason for the exception handler is to enforce a postcondition
> >> that Dirty must be True if Visit raises an exception. However the
> >> warnings suggest that the postcondition cannot be enforced this way.
> >> How should I rewrite my code?
>
> >> --
> >> Ludovic Brenta.
>
> > I think trying to "force" the parameter passing mode to a certain mode
> > is making this more complicated than necessary.  One of the nice
> > things about Ada over other languages is that you generally shouldn't
> > have to worry about whether a parameter is copy-by-value or copy-by-
> > reference.
>
> > In this case, you are trying to use the exception handler to assign a
> > value to the local parameter Dirty so that it can get passed back to
> > the calling subprogram.  This implies the calling subprogram has a
> > parameter in its scope that keeps track of dirtiness, too.  Instead of
> > trying to set Dirty to True in Refresh, why not just raise a user-
> > defined exception (such as Dirty_Error) and have an exception handler
> > in the calling subprogram that catches this exception and sets the
> > *calling subprogram's* variable tracking dirtiness to True?
>
> That's an interesting suggestion but we've patched the run-time library
> so that it dumps core on every exception; we use exceptions only for
> exceptional situations and dumping core freezes the system for 30
> seconds to produce a file roughly 300 MiB in size.  So I would rather
> not raise exceptions that are do not detect a bug.
>
> --
> Ludovic Brenta.

Well, I'm not sure I'm suggesting you raise extra exceptions, just
handle them in the calling subprogram instead of the called
subprogram.  You're already re-raising the exception with the called
subprogram exception handler:

> >> exception
> >>    when others =>
> >>       Dirty := True; -- warnings here
> >>       raise;

You don't have to create a user-defined exception.  Consider the
following code:

type T is private; -- completion elided

generic
   with procedure Visit (Object : in out T);
procedure Refresh (Object : in out T; Dirty : in out T) is
begin
   if Dirty then
      Visit (Object);
      Dirty := False;
   end if;

-- This handler isn't necessary, but I put it here to help illustrate
-- the changes I'm recommending.
exception
   when others =>
      raise;
end Refresh;

*****

procedure Calls_Refresh is

   Obj : T;
   Calling_Scope_Dirty : Boolean;

begin

   -- potentially other code here

   Dirty_Handler_Block :
   begin

      Refresh(Obj, Calling_Scope_Dirty);

   exception
      when others =>
         Calling_Scope_Dirty : True;
         -- potentially other handler code here

   end Dirty_Handler_Block;

   -- potentially other code here

end Calls_Refresh;



  reply	other threads:[~2010-03-14 15:12 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-12  9:13 Ensuring postconditions in the face of exceptions Ludovic Brenta
2010-03-12  9:24 ` Ludovic Brenta
2010-03-12  9:29 ` Niklas Holsti
2010-03-12 11:08   ` Ludovic Brenta
2010-03-12 14:00     ` Jeffrey R. Carter
2010-03-13  3:15       ` Randy Brukardt
2010-03-13 15:14         ` Robert A Duff
2010-03-16  3:13           ` Randy Brukardt
2010-03-16 15:18             ` Robert A Duff
2010-03-16 19:00               ` Adam Beneschan
2010-03-16 20:04                 ` Robert A Duff
2010-03-16 23:23               ` Randy Brukardt
2010-03-13 17:34         ` Jeffrey R. Carter
2010-03-13  7:54 ` Stephen Leake
     [not found] ` <ruqub2y84rqj.179q01lxzgatj$.dlg@40tude.net>
2010-03-13 19:33   ` Georg Bauhaus
2010-03-14 14:05 ` Alex Mentis
2010-03-14 14:21   ` Ludovic Brenta
2010-03-14 15:12     ` Alex Mentis [this message]
2010-03-15  9:14       ` Ludovic Brenta
2010-03-15 11:05         ` cjpsimon
2010-03-15 13:04           ` Ludovic Brenta
2010-03-15 14:16             ` J-P. Rosen
2010-03-15 19:14         ` Jeffrey R. Carter
2010-03-16 19:25           ` Robert Matthews
2010-03-14 15:38     ` Robert A Duff
2010-03-15  8:54       ` Ludovic Brenta
2010-03-15 16:44         ` Robert A Duff
2010-03-15 17:33           ` Ludovic Brenta
2010-03-15 18:36             ` Robert A Duff
2010-03-14 18:57     ` Jeffrey R. Carter
2010-03-15  8:56       ` Ludovic Brenta
2010-03-15 11:04 ` AdaMagica
replies disabled

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