stuartw@tove.cs.umd.edu (Stuart M. Weinstein) (04/30/91)
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) with text_io; procedure t1 is type intarr is array(1..50) of integer; zero : integer; a : integer; arr : intarr; procedure sub1(x : in out integer) is y : integer := 1; begin x := x + 10; y := y / zero; -- raise exception end sub1; procedure sub2(x : in out intarr; i : in integer) is y : integer := 1; begin x(i) := x(i) + 10; y := y / zero; -- raise exception end sub2; begin zero := 0; a := 5; text_io.put_line("Before sub1: A = " & integer'image(a)); begin sub1(a); exception when others => null; end; text_io.put_line("After sub1: A = " & integer'image(a)); arr(12) := 5; text_io.put_line("Before sub1: ARR(12) = " & integer'image(arr(12))); begin sub2(arr,12); exception when others => null; end; text_io.put_line("After sub1: ARR(12) = " & integer'image(arr(12))); end; Output from DEC Ada 2.2: Before sub1: A = 5 After sub1: A = 5 Before sub1: ARR(12) = 5 After sub1: ARR(12) = 15
stt@inmet.inmet.com (05/02/91)
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
smithd@software.org (Doug Smith) (05/03/91)
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...
lee@leo (Bill Lee) (05/03/91)
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 The "Right Thing"??? Yes,.....but..... THERE ARE NO GUARANTEES THAT ANY TWO COMPILERS WILL DO IT THE SAME! Any program that depends on a particular implementation of the values returned (or not returned) in a record or array under the conditions specified is technically erroneous. Sure, it will work on the first compiler/platform, but there is no way to believe that it will work elsewhere. Bill Lee lee@shell.com Shell Oil Co.