home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / programm / prog3 / chap17.txt < prev    next >
Encoding:
Text File  |  1991-07-01  |  20.1 KB  |  469 lines

  1.  
  2.  
  3.  
  4.                                                        Chapter 17
  5.                                                        EXCEPTIONS
  6.  
  7.  
  8. EXCEPTIONS ARE NOT NEW TO YOU
  9. _________________________________________________________________
  10.  
  11. Assuming you have completed part 1 of this tutorial, you have seen
  12. many references to exceptions, but we have said little about how
  13. you can use them.  The purpose of this chapter is to instruct you
  14. on the use of exceptions, and by the time you complete it, you will
  15. have the ability to use exceptions to develop a program with its
  16. own error handling ability.
  17.  
  18.  
  19. WHY DO WE NEED EXCEPTIONS?
  20. _________________________________________________________________
  21.  
  22. The original charter for the development of Ada included the
  23. ability to operate in a real-time environment.  You already
  24. understand, if you have much programming experience, that if it is
  25. possible for an error to surface, it will eventually surface.  Many
  26. programming languages simply terminate operation if a "fatal error"
  27. is detected, but this could be a disaster if the program was
  28. controlling a real-time system upon which human lives or safety
  29. depended.  A 747 in final approach to the airport, or a system used
  30. in a hospital operating room would be two such examples of systems
  31. that simply could not be terminated abruptly because a bad data
  32. point was somehow accumulated.  The careful application of Ada
  33. exceptions will allow the software to gracefully recover from such
  34. a situation rather than aborting operation completely.
  35.  
  36.  
  37. OUR FIRST EXCEPTION
  38. _________________________________________________________________
  39.  
  40. Examine the program named EXCEPT1.ADA for our     ===============
  41. first example program with an exception handler.    EXCEPT1.ADA
  42. Ignore lines 21 and 22 for the moment and you     ===============
  43. will have a program that is not at all unusual,
  44. and should pose no problem for you to
  45. understand.  The program does have a carefully introduced error
  46. however, because when we reach a value of 4 for Index in line 17,
  47. we will be attempting to divide by zero.  Dividing by zero is not
  48. allowed in any programming language, because the answer is infinite
  49. and therefore undefined.  The Ada runtime system will, by
  50. definition, cause the exception named Numeric_Error to be raised,
  51. which is the Ada way of saying that a divide by zero was attempted.
  52. This signals the system to do something about it.  (Actually, there
  53. are many other ways to get the Numeric_Error exception raised but
  54. we will worry about them later.)
  55.  
  56.  
  57.  
  58.                                                         Page 17-1
  59.  
  60.                                           Chapter 17 - Exceptions
  61.  
  62. The Ada system will search, in a very definite way, for any
  63. instructions we have given about this error, and if it finds none,
  64. will terminate operation of the program after issuing a message
  65. concerning the error.  If we have given instructions about what to
  66. do with the error, it will execute the instructions and continue
  67. operation as we direct it to do.  The method of giving the system
  68. these instructions is illustrated in lines 21 and 22.
  69.  
  70.  
  71. HOW ARE EXCEPTIONS HANDLED?
  72. _________________________________________________________________
  73.  
  74. When any exception is raised, the system immediately looks at the
  75. end of the current block or subprogram for the reserved word
  76. exception.  If it is found, and if the specific exception that was
  77. raised is defined there, the instructions associated with that
  78. exception are executed, and the subprogram or block is exited.
  79.  
  80. To define a handler for a specific exception, the reserved word
  81. when is used, followed by the name of the exception, and finally
  82. the sequence of statements to be executed following the =>
  83. operator.  The sequence of statements can be of arbitrary
  84. complexity, but should be kept simple due to the nature of
  85. exception handling.  In this case, we output a message to the
  86. monitor and do nothing else.  As many different exceptions as
  87. desired can be handled at the end of any block or subprogram by
  88. adding additional constructs of the form,
  89.  
  90.      when <exception_name> => instructions;
  91.  
  92. following the single instance of the reserved word exception.  We
  93. will study examples of multiple exception handlers later in this
  94. chapter.
  95.  
  96.  
  97.  
  98. WHAT HAPPENS FOLLOWING EXCEPTION HANDLING?
  99. _________________________________________________________________
  100.  
  101. Following handling of the exception, the program executes an
  102. otherwise normal return to the calling program, and the normal
  103. sequence of instructions in the calling program is executed.  Note
  104. that it is impossible to jump back into the subprogram or block in
  105. which the exception was raised from the exception handling routine
  106. at the end of that block.  In this case, because of the logic used,
  107. the loop defined in line 13 is terminated early because we
  108. essentially jumped out of the loop and the program is ended.  If
  109. an exception handler or a group of exception handlers is included,
  110. it must be the last thing in the block.  If normal execution of the
  111. block reaches the end of the executable statements by coming to the
  112. reserved word exception, the block is terminated normally.  You
  113. cannot drop into the exception handler at the end of a block.  The
  114. only way to get to the exception handling code is through raising
  115. an exception.
  116.  
  117.                                                         Page 17-2
  118.  
  119.                                           Chapter 17 - Exceptions
  120.  
  121.  
  122. In spite of the additional questions you have at this point,
  123. compile and execute this program.  Observe the results, and if you
  124. do not understand the output, reread the above text until you do,
  125. because these fundamental points are essential to understanding the
  126. entire topic of exceptions.
  127.  
  128.  
  129.  
  130. LET'S USE SEVERAL EXCEPTIONS
  131. _________________________________________________________________
  132.  
  133. Examine the program named EXCEPT2.ADA for         ===============
  134. additional examples of exceptions.  This program    EXCEPT2.ADA
  135. will answer many of your questions about          ===============
  136. exceptions.
  137.  
  138. The portion of the program defined in lines 46 through 50, along
  139. with its associated procedure is logically identical to the last
  140. example program except for the loop being moved to the calling
  141. program.  When the divide by zero is detected by the system, which
  142. raises the Numeric_Error exception, the exception is handled by the
  143. exception handler defined in lines 20 and 21, and the return to the
  144. calling program is effected.  In this case however, when control
  145. returns to the calling program, we are still inside of the loop,
  146. and the loop completes normally.  This should indicate to you that
  147. by careful selection of where you handle exceptions, you can
  148. control the overall result.  We will see more about this as we
  149. continue our study of exceptions.
  150.  
  151. The logic of the second group of instructions, found in lines 52
  152. through 67, is identical to the logic of the first group as studied
  153. in the last paragraph.  The only difference is that the procedure
  154. has been changed into a block and inserted into the code in an
  155. inline fashion.  This has been done to illustrate the use of an
  156. exception in a block of code, and to illustrate that the exception
  157. handler for the block of code is put at the end of that block.
  158. After the exception is raised and handled, execution begins at the
  159. first statement following the block.  Because the block is
  160. contained within the loop, the exception is handled within the loop
  161. and the loop runs to completion.
  162.  
  163.  
  164.  
  165. MULTIPLE EXCEPTION HANDLERS
  166. _________________________________________________________________
  167.  
  168. Finally, we come to the section of code in lines 69 through 72,
  169. consisting of a simple loop calling the procedure New_Divide_Loop.
  170. The procedure itself, defined in lines 24 through 43, contains an
  171. example of a new operation, the ability to make up our own
  172. exception, raise it ourself, and handle it with our own exception
  173. handler.
  174.  
  175.  
  176.                                                         Page 17-3
  177.  
  178.                                           Chapter 17 - Exceptions
  179.  
  180. Line 25 declares the identifier My_Own_Exception as being the name
  181. of an exception, and is defined in much the same way that we would
  182. declare a variable.  We cannot assign a value to it, but we can
  183. raise it anywhere within its defined scope which is the same as the
  184. scope of a variable declared at the same place.  The exception is
  185. automatically initialized to the "not raised" condition by the
  186. system.
  187.  
  188. Beginning in line 37, we define three different exception handlers,
  189. which will cover any exceptions raised anywhere within this
  190. procedure.  The first two are named exception handlers but the
  191. third handler uses the reserved word others to indicate that it
  192. will be used for any exceptions that are not handled by the two
  193. named exception handlers.  The others clause is optional, but if
  194. it is included, it must be last.
  195.  
  196.  
  197.  
  198. RAISING AN EXCEPTION
  199. _________________________________________________________________
  200.  
  201. If we reach line 31 with a value of 4, which we eventually will
  202. because of the logic of the calling program, we will detect the
  203. divide by zero that would be attempted upon reaching line 34.
  204. Instead of letting the system generate the exception named
  205. Numeric_Error, we generate our own exception named
  206. My_Own_Exception, using the reserved word raise followed by the
  207. name of the exception.  As soon as we raise this exception, the
  208. system jumps to the end of the block, looks for the reserved word
  209. exception, which it finds, then looks for the exception handler
  210. with the name that was raised.  Upon finding it, the statements are
  211. executed, resulting in a message being output to the display, and
  212. a return is effected to the calling program.
  213.  
  214. In this case, the system will not raise the exception
  215. Numeric_Error, because we are detecting the error before it
  216. actually happens.  You could raise it yourself by inserting the
  217. statement "raise Numeric_Error;" somewhere in this procedure,
  218. possibly when the value of Index is equal to 3.  It would be a good
  219. exercise for you to insert that in the code to see that you can
  220. raise one of the system exceptions as well as your own.
  221.  
  222. Be sure to compile and execute this program to verify proper
  223. operation according to this description and to ascertain your
  224. understanding of the same.
  225.  
  226. Note that if an exception occurs, formal parameters of mode out or
  227. in out are not updated since a normal return is not accomplished.
  228. Partial results will therefore not be returned to the calling
  229. program.  This is not illustrated here, but is left for the student
  230. to investigate if desired.
  231.  
  232.  
  233.  
  234.  
  235.                                                         Page 17-4
  236.  
  237.                                           Chapter 17 - Exceptions
  238.  
  239. WHAT ARE THE PREDEFINED EXCEPTIONS?
  240. _________________________________________________________________
  241.  
  242. There are five predefined exceptions which can be raised by the
  243. system to indicate a very specific problem.  A brief definition
  244. follows;
  245.  
  246. Constraint_Error - This will occur if something goes out of its
  247.      assigned range.
  248.  
  249. Numeric_Error - This will occur if something goes wrong with
  250.      arithmetic such as the attempt to divide by zero illustrated
  251.      in this chapter.
  252.  
  253. Program_Error - This will occur if we attempt to violate an Ada
  254.      control structure such as dropping through the bottom of a
  255.      function without a return.
  256.  
  257. Storage_Error - This will occur if we run out of storage space
  258.      through either recursive calls or storage allocation calls.
  259.  
  260. Tasking_Error - This will occur when attempting to use some form
  261.      of tasking in violation of the rules.
  262.  
  263. All five of these exceptions are defined in detail in section 11.1
  264. of the LRM.
  265.  
  266.  
  267.  
  268. WHAT ABOUT AN UNHANDLED EXCEPTION?
  269. _________________________________________________________________
  270.  
  271. Examination of the program named EXCEPT3.ADA      ===============
  272. will reveal what happens if an exception is         EXCEPT3.ADA
  273. raised that is not handled by the program.  In    ===============
  274. a word, the program will be terminated, but we
  275. need to understand how termination occurs so we
  276. can intelligently prevent it.
  277.  
  278. There is a loop in the main program which calls two procedures
  279. successively, Divide_By_Zero and Raise_An_Error.  The first
  280. procedure is identical to that in the first two example programs
  281. and the only exception raised is Numeric_Error, which is handled
  282. properly.
  283.  
  284. The second procedure has its own exception defined, named
  285. My_Own_Error which it raises and handles itself in the manner
  286. defined previously in this chapter.  It also has a divide by zero
  287. problem in line 29 that will raise the exception Numeric_Error when
  288. Count is equal to 6.  Of course, the logic is defined to make this
  289. happen and illustrate the error.
  290.  
  291.  
  292.  
  293.  
  294.                                                         Page 17-5
  295.  
  296.                                           Chapter 17 - Exceptions
  297.  
  298. PROPAGATION OF EXCEPTIONS
  299. _________________________________________________________________
  300.  
  301. When the exception Numeric_Error is raised at line 29, the system
  302. searches for the reserved word exception which it finds in line 34
  303. at the end of the procedure.  It then searches for a sequence of
  304. statements for Numeric_Error which it does not find.  Since an
  305. exception handler is not found within the procedure, the exception
  306. is propagated to the calling program in such a way that the
  307. exception appears to have been raised by the calling statement.
  308. In this case it will appear to the logic as if the exception
  309. Numeric_Error was raised by the statement in line 42.  Once again,
  310. the exception rules are applied, and the system searches for an
  311. exception block at the end of the block or subprogram, in this case
  312. being the main program.  Finding the reserved word exception in
  313. line 46, the system looks for the desired exception handler, which
  314. it finds and executes, then drops out of the bottom of the main
  315. program which initiates a return to the operating system.
  316.  
  317. If there were no handler for the exception, the exception would be
  318. propagated to the operating system, and it would issue some sort
  319. of nasty message about an unhandled exception leading to program
  320. termination.
  321.  
  322. It should be somewhat obvious to you that if you added another
  323. level of subprogram nesting, you could report the error yourself,
  324. and possibly recover operation of the program.  It is all a matter
  325. of program definition.
  326.  
  327.  
  328. CAN YOU EXECUTE AN EXCEPTION WITHOUT RAISING IT?
  329. _________________________________________________________________
  330.  
  331. As mentioned before, the section of code at the end of the program,
  332. following the reserved word exception, is never executed without
  333. raising an exception.  It can never be executed by dropping into
  334. it.
  335.  
  336. Be sure to compile and execute this program to observe the
  337. operation of the exceptions.
  338.  
  339.  
  340. EXCEPTIONS CAN OCCUR DURING DECLARATIONS
  341. _________________________________________________________________
  342.  
  343. Examine the program named EXCEPT4.ADA for an      ===============
  344. example of an exception that occurs during the      EXCEPT4.ADA
  345. declaration part of the program.                  ===============
  346.  
  347. When a procedure is called, its declarations are
  348. elaborated prior to the logic being executed, as we have stated
  349. before.  If one of the declarations cannot be properly elaborated,
  350. then an error occurs and an exception is raised.  Examining the
  351. procedure Try_It will reveal an error in lines 8 through 10, where
  352.  
  353.                                                         Page 17-6
  354.  
  355.                                           Chapter 17 - Exceptions
  356.  
  357. the variable Funny is declared to be of type LIMIT_RANGE with
  358. limits of 14 through 23, then it is initialized to the value 8.
  359. Since this is out of the allowed range, the exception
  360. Constraint_Error will be raised.  The executable part of the
  361. procedure is not yet ready for use, so the exception handler
  362. defined within it cannot be used, and the exception will be
  363. propagated to the calling program where it will be handled just as
  364. if it occurred in the calling statement, which is line 22 in this
  365. case.  The exception will therefore be handled by lines 24 through
  366. 26 of the procedure Try_To_Fix_It.  Be sure to compile and run this
  367. program, then study the results.
  368.  
  369.  
  370. ADDITIONAL PREDEFINED EXCEPTIONS
  371. _________________________________________________________________
  372.  
  373. You will find that there are actually additional exceptions
  374. predefined by your compiler, but these are all defined in
  375. additional packages supplied with your compiler.  Packages such as
  376. Text_IO, Sequential_IO, or Calendar (to be discussed later with
  377. tasking), have some number of exceptions defined as a part of their
  378. interfaces, but there are only five exceptions predefined as a part
  379. of Ada.  These were listed and discussed earlier.
  380.  
  381.  
  382. A FEW MORE TOPICS CONCERNING EXCEPTIONS
  383. _________________________________________________________________
  384.  
  385. The example program named EXCEPT5.ADA             ===============
  386. illustrates a few additional topics about           EXCEPT5.ADA
  387. exceptions and illustrates how they are used in   ===============
  388. a package.  This is a very strange program with
  389. lots of exception handling examples for your
  390. study.  You will be left on your own to study the overall operation
  391. of this program, but the unique exception handling techniques will
  392. be pointed out to you.
  393.  
  394. The package body contains a section of initialization code in lines
  395. 37 through 48 which is composed of nothing but a null statement and
  396. several exception handlers.  These are only used during
  397. initialization of the package since they are not within the
  398. executable portion of either of the subprograms.  You will notice
  399. that the exception named Funny_Add_Error is declared in the package
  400. specification so it is visible in the exception handler in line 44,
  401. but the exception named Funny_Subtract_Error is not visible there
  402. because it is declared within the function.  We will see soon
  403. however, that even this exception can be propagated to the main
  404. program.
  405.  
  406. When the program is executing, a call to the function Subtract_One
  407. raises the exception Funny_Subtract_Error which is handled by the
  408. exception handler at the end of the function in line 32.  A message
  409. is displayed and the same exception is raised by the isolated raise
  410. statement in line 34.  This statement simply raises the exception
  411.  
  412.                                                         Page 17-7
  413.  
  414.                                           Chapter 17 - Exceptions
  415.  
  416. that caused the jump to the exception handler in the first place.
  417. The isolated raise statement can only be used within an exception
  418. handler.  The exception is passed on to the calling program.
  419.  
  420. Because the exception named Funny_Subtract_Error is not visible to
  421. the main program, it cannot handle it by name but even this
  422. exception can be handled by an others clause as is done in line 66.
  423. After printing a message, the same exception is once again raised
  424. in line 68 where it is passed on to the operating system.  You will
  425. see when you execute this program that the exception is known by
  426. name to the operating system.  It will give you a nasty message
  427. about an unhandled exception and terminate operation.
  428.  
  429.  
  430. THE others CLAUSE IN AN EXCEPTION HANDLER
  431. _________________________________________________________________
  432.  
  433. If the others clause is used, it must be the last exception handler
  434. and it cannot be combined with any other exceptions such as
  435. illustrated in line 62.  As in other Ada constructs, two or more
  436. exceptions can be "or"ed and use the same exception handler.
  437.  
  438. Note line 57 where an exception is renamed to reduce the length of
  439. its name.  Any exception can be renamed in a similar fashion.
  440.  
  441. Be sure to compile and execute this program and spend the time
  442. necessary to understand the exception propagation illustrated here.
  443.  
  444.  
  445.  
  446. PROGRAMMING EXERCISES
  447. _________________________________________________________________
  448.  
  449. 1.   Change line 34 of EXCEPT2.ADA to cause a divide by zero when
  450.      Index is equal to 2 and see that both exceptions will be
  451.      handled correctly.
  452.  
  453. 2.   Also in EXCEPT2.ADA, declare a new exception in line 25, and
  454.      raise it in line 32 to see how the others clause handles it.
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.                                                         Page 17-8