Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of exceptions in Ada

Tags:

ada

I'm looking for style guidance. In Python, exceptions are used as "normal" operations:

try:
    z = x/y
except ZeroDivisionError:
    z = 73.0    # set z if y is zero

Rather than checking for y being near zero, we do the division and catch the exception.

This type of approach is illustrated in Ada in "Programming in Ada 2012" by John Barnes:

begin
    Tomorrow := Day'Succ(Today);
exception
    when Constraint_Error =>
        Tomorrow := Day'First;

But then, the book goes on to say "This is a really bad example. Exceptions should be used for rarely occurring cases...".

I am new to Ada, is it good Ada programming style to use exceptions to avoid if statements as we do in Python? Or are exceptions really just used in Ada for nasty things?

like image 776
Chris Hobbs Avatar asked Jul 22 '20 15:07

Chris Hobbs


People also ask

What are the four exceptions defined in the standard package of Ada?

Exception handlers can be included in blocks or in the bodies of subprograms, packages, or tasks. 10. What are the four exceptions defined in the Standard package of Ada ? – Constraint_Error,Program_Error,Storage_Error, and Tasking_Error.

What are the uses of exceptions?

Exceptions provide the means to separate the details of what to do when something out of the ordinary happens from the main logic of a program. In traditional programming, error detection, reporting, and handling often lead to confusing spaghetti code.

How is a user defined exception defined in Ada?

Ada gives the user the ability to define their own exceptions. These are placed in the declarative part of the code. They can be placed whereever a normal declaration is placed (e.g. even in package specifications).


2 Answers

A major difference from Python is that in Ada, exceptions are not data types. The only data you can associate with an instance of an exception is a String:

raise My_Exception with "some string";

So when catching an exception, we can only ever know which kind of exception got thrown, and get some String which may be useful for logging, but not so much for programmatically analyzing what went wrong in more detail.

This also means that we don't have a way to chain exceptions, like it is often done e.g. in Java, where an exception is often wrapped inside another exception to hide details while still being able to see in the stack trace what exactly went wrong.

The reason for this is that the language has been designed for exceptions to be used scarcely. Unlike Python, Ada has been designed to target bare metal, where you may want to disable runtime checks for performance reasons. If you do that, you won't get the Constraint_Error on division by zero and the program will have undefined behavior. So using exceptions influences code portability negatively.

Some compilers provide additional options, like the No_Exception_Propagation restriction in GNAT, which allows exception only if they are caught within the same subroutine.

Still, exceptions are a useful tool for communicating failure without completely obstructing normal program flow in the code (you will know what I mean if you've ever written Go, or C). But generally, the Ada Style Guide advises that

Exceptions should be used as part of an abstraction to indicate error conditions that the abstraction is unable to prevent or correct. Because the abstraction is unable to correct such an error, it must report the error to the user.

This means that, if you do have the possibility to correct a problem without using an exception, you should do that, because it should be part of the normal, non-exceptional, program flow.

like image 194
flyx Avatar answered Oct 10 '22 21:10

flyx


Ada exception handling syntax does not use a try-catch mechanism. Because of that the exception handler is often separated from the code raising the exception by many lines of source code. Ada exceptions are expected to be used for truly exceptional problems. A more acceptable style for Ada is shown below.

  if Today < Day'Last then
     Tomorrow := Day'Succ(Today);
  else
     Tomorrow := Day'First;
  end if;

This code pattern retains the relationship between the two conditions in close proximity in the source code. Neither condition is an erroneous condition or an exceptional condition.

Historically Ada style favors readability over compactness of writing, however the Ada 2012 standard does allow conditional expressions such as

Tomorrow := (if Today < Day'Last then Day'Succ(Today) else Day'First);

It may be a matter of taste whether or not to use a conditional expression.

like image 31
Jim Rogers Avatar answered Oct 10 '22 22:10

Jim Rogers