1

I am working with a linked list stack and I want it to get an Underflow error so I can see that it is working properly. It, however, keeps giving me a constraint error message where I want there to be the underflow message. Any tips on what to do would be helpful. I cannot put up the code at the current moment for my server is down but I will update this as soon as I can

j.Shry
  • 29
  • 5
  • Your linked list is certainly having some operations, either named ones, or ones that manipulate the list's nodes. One of these operations raises `Constraint_Error`. Is this operation specifically tied to the underflow condition, or are there other circumstances that can also make it raise `Constraint_Error`? Can you tie one operation to underflow using additional information, such as the state of list variables? If so, then this fact becomes usable together with Brian Drummond's answer. – B98 Jan 14 '17 at 19:43

1 Answers1

5

Two ways : (okay, three...)

(1) The clean way : Ensure you don't violate the constraint in the underflow condition.

You may think it's slow because of the explicit check. However, regardless of whether that counts as premature optimisation, the check happens implicitly anyway to raise Constraint_Error. Whether this actually costs any time depends on your compiler and optimisation level. With a good compiler it probably won't.

Underflow_Error : Exception;
Declare
   A,B,C : Natural;
   D : Integer; -- a "bigger" type that can accommodate the worst case value
Begin
   -- A := B - C; -- may raise constraint error
   D := B - C;
   if D < 0 then 
      raise Underflow_Error;
   else 
      A := D;
   end if;
End;

(2) Catch the constraint error and raise yours instead. This is unclean because any other Constraint Error in the same scope will (misleadingly) be converted to Underflow Error.

Underflow_Error : Exception;
Declare
   A,B,C : Natural;
Begin
   A := B - C; -- Let it raise constraint error
Exception:
   when Constraint_Error =>  -- convert to my exception
      raise Underflow_Error;
   -- when others => raise;     -- un-handled exceptions are passed upwards anyway
End;

(3) Variant of (2) Catch the constraint error, perform post mortem analysis and raise appropriately. The additional computation is only in the exceptional case, so has essentially no performance impact.

Underflow_Error : Exception;
Declare
   A,B,C : Natural;
Begin
   A := B - C; -- Let it raise constraint error
Exception:
   when Constraint_Error =>   -- if appropriate, convert to my exception
      if B - C < 0 then
         raise Underflow_Error;
      else 
         raise;
      end if;
End;
  • I don’t think you need the `when others => raise;`? – Simon Wright Jan 13 '17 at 22:03
  • @SimonWright You are of course correct. Excess of caution on my part. Exceptions not explicitly trapped are passed on anyway. But if you have a 'when others` (e.g. to log that the exception occurred here) nad you don't want to eat the exceptions, then a "raise" will pass it to the outer handlers. –  Jan 13 '17 at 22:28