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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sample.eng.ohio-state.edu!purdue!haven.umd.edu!uvaarpa!software.org!smithd From: smithd@software.org (Doug Smith) Newsgroups: comp.lang.ada Subject: Re: Updating IN OUT's after exceptions Summary: Programming style suggestions Keywords: Ada, programming style, in out, exceptions Message-ID: <1991May2.171011.26528@software.org> Date: 2 May 91 17:10:11 GMT References: <33747@mimsy.umd.edu> <20600103@inmet> Sender: usenet@software.org (Usenet News/Mail Support) Organization: spd List-Id: In article <20600103@inmet> stt@inmet.inmet.com writes: > > Re: Updating IN OUT's after exceptions > Query on 5:18 am Apr 30, 1991 by stuartw@tove.cs.umd.edu > > > In the enclosed program, I raise an exception inside a subroutine after > > making an assignment to an IN OUT parameter. In the first case, the > > parameter is a scalar, in the second it is not. Everything else is the > > same, except the resulting behavior. Is this permitted by the LRM? > > I know that compilers can pass non-scalar parameters by copy-in/copy-out > > or reference, but should that effect exception handling? Is Ada/9x > > addressing this? > > > > Thanks. > > > > Stuart. (weinstei@kong.gsfc.nasa.gov) > > The Good Old Reference Manual, section 6.2:12 says the following: > If the execution of a subprogram is abandoned as a result of an exception, > the final value of an actual parameter [...] can be either its > value before the call [if passed by copy] or a value assigned > to the formal parameter during the execution of the subprogram > [if passed by reference]. > > In other words, the compiler "does the right thing." > > S. Tucker Taft > Intermetrics, Inc. > Cambridge, MA 02138 I have adopted a rather obvious programming style to avoid this ambiguity, and to help maintain data integrity (an even higher priority): Do not change an 'in out' parameter until there is little to no chance of an exception being raised. This can be accomplished two ways: o First! Explicitly check for exceptional conditions and raise the exception before attempting to update an 'in out' parameter. This is essential for limited private types that have no assignment procedure (see next bullet). o Use additional local variables to hold intermediate results, and don't forget to clean up any garbage that might be generated (you may exit the routine normally or through the exception handler!). Don't forget that passing a formal parameter as parameter to another routine could modify it then raise an exception! Not everyone holds to the high morals of data integrity (nor can they afford to when performance is critical). Some of you may not have this luxury (i.e. hard-real-time applications programmers), but I extend this guideline to array parameters! That means, if necessary, copying the formal parameter to a local array, modifying the local array, then if no exceptions were raised, copying the local array back to the formal parameter (immediately before exiting the routine). Of course, I avoid this almost all of the time by using the 'First!' bullet described above. Then, since most array usage can be isolated to generic data structure utilities (iterators, selectors, constructors galore!), I almost never deal with arrays directly. There are several issues of data integrity to deal with when the limited private types are implemented as pointers (to arrays), but let's not delve too deep...