From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,c80e6f742e73478f X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post02.iad.highwinds-media.com!news.flashnewsgroups.com-b7.4zTQh5tI3A!not-for-mail Newsgroups: comp.lang.ada Subject: Re: Ensuring postconditions in the face of exceptions References: <820d96c0-5d67-4b8c-8c5b-811ca4f1127e@g26g2000yqn.googlegroups.com> From: Stephen Leake Date: Sat, 13 Mar 2010 02:54:35 -0500 Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (windows-nt) Cancel-Lock: sha1:UkpUD43KaI6HtfLd9eFVxriIvw4= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Complaints-To: abuse@flashnewsgroups.com Organization: FlashNewsgroups.com X-Trace: 7d01f4b9b44dde197caa708927 Xref: g2news1.google.com comp.lang.ada:9554 Date: 2010-03-13T02:54:35-05:00 List-Id: Ludovic Brenta writes: > 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? I don't see the point; Visit is not called if Dirty is not True, so you don't need to do anything in an exception handler. So I would rewrite it by deleting the exception handler, and maybe adding a comment. Unless you meant the opposite; if Dirty is supposed to be changed to False on exception from Visit, then you need to set Dirty in the handler. But that doesn't seem to make sense, given what Dirty seems to mean. It would be clearer to localize the exception handler: generic with procedure Visit (Object : in out T); procedure Refresh (Object : in out T; Dirty : in out T) is begin if Dirty then begin Visit (Object); exception when others => Dirty := True; -- warnings here raise; end; Dirty := False; end if; end Refresh; but that's minor. -- -- Stephe