[net.lang.ada] Exception handling question

holden@cca.UUCP (Russ Holden) (10/03/86)

The following language fragment (in a slightly different
form) was written here (really!).  It was found to
perform differently on the Rational and VAX/VMS compilers.  
On the Rational "Missed it" is printed while on VMS 
"Got it" is printed.

Logic and the LRM both seem to indicate that the innermost
handler should get control and "Got it" should be printed.
Section 11.4 says that "The selection of this handler depends
on whether the exception is raised during the execution of
statements or during the elaboration of declarations".  It
says nothing about whether the exception is raised with
using a "raise" or a "raise <exception_name>" as some here
have claimed.  Is this right? 

with Textio;

procedure Foo is
   Bar : exception;
begin
    begin
        begin
            raise Bar;
        exception
            when Bar =>
                begin
                    raise;
                exception
                    when Bar =>
                        Textio.Put_Line("Got it");
                end;
        end;
    exception
        when Bar =>
            Textio.Put_Line("Missed it");
    end;
end Foo;
-- 
Russell Holden
Computer Corporation of America
Four Cambridge Center
Cambridge, MA 02142

eric@burdvax.UUCP (Eric Marshall) (10/06/86)

	I tried the same program on three validated compilers
we have in house and have included the results. For reasons I
will not discuss, I am unable to release the names of the compilers.
Here are the results:

	1) One compiler flagged the 'raise;' statement as an error,
	   and provided a reference to LRM paragraph 11.3.3. Changing
	   the statement to 'raise Bar;', the generated program printed
	   Got it.

	2) One program printed Missed it.

	3) One program aborted due to an unhandled exception.


	This program sounds like a good candidate for future ACVC's.
-- 


Eric Marshall
System Development Corporation, a Burroughs Company
P.O. Box 517
Paoli, PA. 19301
(215) 648-7223

USENET: sdcrdcf!burdvax!eric
        {sjuvax,ihnp4,akgua,cadre}psuvax1!burdvax!eric
ARPANET: PAYTON@BBNG

GOODENOUGH@A.ISI.EDU (John B. Goodenough) (10/07/86)

A test to check that the proper exception is raised (and handled) within the
block will be added to the ACVC (quite possibly, in the next version, which
is due for release in December).  This kind of example is helpful in
improving the quality of the ACVC and the behavior of validated compilers.
-------

eric@burdvax.UUCP (Eric Marshall) (10/09/86)

	What is the current interpretation of the posted program?

	One of the compilers I tested it on detected an error on the
'raise;' statement, and gave a reference to LRM paragraph 11.3.3.
Reading this paragraph, it seems to say that the posted program
is illegal, and the compiler is correct. The LRM paragraph says

	the raise statement with no exception name is only allowed in
	an exception handler, but not in the sequence of statements of
	a subprogram, ... enclosed by the handler.

All of these additional constructs can only be introduced by
a block statement. The paragraph never explicitly addresses the
raising of the exception in the statements of the block, therefore
it seems the posted program is indeed illegal.
-- 


Eric Marshall
System Development Corporation, a Burroughs Company
P.O. Box 517
Paoli, PA. 19301
(215) 648-7223

USENET: sdcrdcf!burdvax!eric
        {sjuvax,ihnp4,akgua,cadre}psuvax1!burdvax!eric
ARPANET: PAYTON@BBNG

jankok@mcvax.uucp (Jan Kok) (10/13/86)

In article <2737@burdvax.UUCP> eric@burdvax.UUCP (Eric Marshall) writes:
>                . . .                    The LRM paragraph says
>
>	the raise statement with no exception name is only allowed in
>	an exception handler, but not in the sequence of statements of
>	a subprogram, ... enclosed by the handler.
>
>All of these additional constructs can only be introduced by
>a block statement. The paragraph never explicitly addresses the
>raising of the exception in the statements of the block, therefore
>it seems the posted program is indeed illegal.

I disagree: I think the original program is correct Ada (provided
that Textio is replaced by Text_Io of course). A raise statement
without an exception name is allowed, it is not a subprogram, package,
task or generic unit, to which the forbidding rule quoted applies.

To return to the posted program: it is not clear to me (but I may be
oversuspicious) whether the systems which cause printing "Missed it"
missed the first or the second exception handler, and I suggest to
insert an extra Put_Line to ascertain this. So my proposed
modification is:

with Text_Io; -- was Textio in original

procedure Foo is
   Bar : exception;
begin
    begin
        begin
            raise Bar;
        exception                     -- Handler 1
            when Bar =>
                begin
                    Text_Io.Put_Line("Handler 1 got it");
                    raise;
                exception             -- Handler 2
                    when Bar =>
                        Text_Io.Put_Line("Handler 2 got it");
                end;
        end;
    exception                         -- Handler 3
        when Bar =>
            Text_Io.Put_Line("Some handler missed it");
    end;
end Foo;
-- 

Russell did not write that changing "raise;" into "raise Bar;"
corrected the performance for the failing compiler (did he?).
-- 
Mail: Jan Kok, CWI (afd. NW), Postbus 4079, NL-1009 AB Amsterdam, Nederland
UUCP: jankok@mcvax.uucp
---------------------------------------------------------------
   One of the Warner Bros to Albert Einstein:
      I have a theory about relatives myself : Don't hire them!

stt@ada-uts (10/25/86)

I don't agree with your conclusion.  Things are generally legal
if not specifically disallowed in cases like this, so
"raise;" inside of a nested block, loop, if, case, etc. is perfectly
legal.  It is only illegal when inside a nested unit/accept statement.
Similar rules apply to return, exit <name>, etc., and these
are certainly legal inside nested blocks (see 5.7, 5.8, 5.9).

S. Tucker Taft
c/o Intermetrics, Inc.
733 Concord Ave
Cambridge, MA  02138