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