Previous | Next | Table of Contents | Index | Program List | Copyright

5.9 System Structures: Introduction to Exception Handling

It is useful to take a close look at Program 5.21 and make a list of the things that could go wrong with its execution:

As written, Program 5.21 will terminate if any of these conditions arises, and the Ada "run-time system" will display a message. Generally the name of the exception will be displayed, but otherwise the form of the message depends upon the compiler.

Ada provides a useful mechanism called exception handling, which allows the programmer to "catch" the exception before it goes to the Ada run-time system. The programmer can supply, at the bottom of the program, procedure, or function, a set of statements, called exception handlers, indicating what is to be done in case an exception is raised. Later chapters, beginning with Chapter 6, will introduce exception handling systematically; for now, Program 5.22 shows you the general idea.

Program 5.22
Sum and Factorial with Exception Handling

WITH Ada.Text_IO;
WITH Ada.Integer_Text_IO;
WITH Useful_Functions;
PROCEDURE Robust_Sum_Fact IS
------------------------------------------------------------------------
--| Prompts the user for an integer N from 1 to 10 
--| and displays the sum and factorial of all integers from
--| 1 to N. Sum and Factorial are gotten from package Useful_Functions.
--| This version incorporates an exception handler part.
--| Author: Michael B. Feldman, The George Washington University
--| Last Modified: July 1995               
------------------------------------------------------------------------

  SUBTYPE OneToTen IS Positive RANGE 1..10;

  MaxNum:       OneToTen;  -- input - a value from 1-10
  SumToCount:   Positive;  -- output - sum of integers from 1-Count
  ProdToCount:  Positive;  -- output - product of integers from 1-Count

BEGIN -- Robust_Sum_Fact

  Ada.Text_IO.Put (Item => "Please enter an integer from 1 to 10 > ");
  Ada.Integer_Text_IO.Get (Item => MaxNum);
  Ada.Text_IO.New_Line;

  Ada.Text_IO.Put(Item => "  N    Sum    Factorial");
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put(Item => "  ----------------------");
  Ada.Text_IO.New_Line;

  FOR Count IN 1..MaxNum LOOP
    SumToCount   := Useful_Functions.Sum (N => Count);
    ProdToCount  := Useful_Functions.Factorial (N => Count);

    Ada.Integer_Text_IO.Put (Item => Count, Width => 3);
    Ada.Integer_Text_IO.Put (Item => SumToCount, Width => 7);
    Ada.Integer_Text_IO.Put (Item => ProdToCount, Width => 9);
    Ada.Text_IO.New_Line;
  END LOOP;

EXCEPTION

  WHEN Constraint_Error =>
    Ada.Text_IO.Put (Item => "The input value is out of range.");
    Ada.Text_IO.New_Line;
  WHEN Ada.Text_IO.Data_Error =>
    Ada.Text_IO.Put (Item => "The input value is not well formed.");
    Ada.Text_IO.New_Line;

END Robust_Sum_Fact;
Sample Run
Please enter an integer from 1 to 10 > 11
The input value is out of range.

Notice that at the bottom of the program, there is a section:

    EXCEPTION
    	WHEN Constraint_Error =>
            Ada.Text_IO.Put(Item => "The input value is out of range.");
            Ada.Text_IO.New_Line;
    	WHEN Ada.Text_IO.Data_Error =>
            Ada.Text_IO.Put
            	(Item => "The input value is not well formed.");
            Ada.Text_IO.New_Line;
    
    END RobustSumFact;

Each group of statements beginning with WHEN is called an exception handler. If the program executes normally, execution stops at the "normal" last statement (the last line before the word EXCEPTION); it is as though the exception-handling section were not there. However, if an exception is raised anywhere in the program, execution of the statement causing the exception is halted, and control is passed immediately to the appropriate exception handler. Once the handler's statements have been executed (in this case, displaying a message), the program terminates normally. There is no message dispayed by the run-time system; because the program handled its own exception, the run-time system has no need to do so.

How useful is this? We will see in Chapter 6 how exception handling can make programs much less prone to terminate with error messages from the run-time system and also how exception handling can be used to ensure the validity of user input. In the simple case considered here, the usefulness of exception handling is that it allows the programmer to control the form of the message displayed when the program terminates. This is better than leaving it to the run-time system, the form of whose messages depends on the compiler.


Previous | Next | Table of Contents | Index | Program List | Copyright

Copyright © 1996 by Addison-Wesley Publishing Company, Inc.