(octave.info)Exception and Error Handling in Oct-Files


Next: Documentation and Testing of Oct-Files Prev: Input Parameter Checking in Oct-Files Up: Oct-Files
Enter node , (file) or (file)node

A.1.12 Exception and Error Handling in Oct-Files
------------------------------------------------

Another important feature of Octave is its ability to react to the user
typing <Control-C> during extended calculations.  This ability is based
on the C++ exception handler, where memory allocated by the C++
new/delete methods is automatically released when the exception is
treated.  When writing an oct-file which may run for a long time the
programmer must periodically use the macro ‘OCTAVE_QUIT’, in order to
allow Octave to check and possibly respond to a user typing <Control-C>.
For example:

     for (octave_idx_type i = 0; i < a.nelem (); i++)
       {
         OCTAVE_QUIT;
         b.elem (i) = 2. * a.elem (i);
       }

   The presence of the ‘OCTAVE_QUIT’ macro in the inner loop allows
Octave to detect and acknowledge a <Control-C> key sequence.  Without
this macro, the user must either wait for the oct-file function to
return before the interrupt is processed, or the user must press
<Control-C> three times which will force Octave to exit completely.

   The ‘OCTAVE_QUIT’ macro does impose a very small performance penalty;
For loops that are known to be small it may not make sense to include
‘OCTAVE_QUIT’.

   When creating an oct-file that uses an external library, the function
might spend a significant portion of its time in the external library.
It is not generally possible to use the ‘OCTAVE_QUIT’ macro in this
case.  The alternative code in this case is

     BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
     ...  some code that calls a "foreign" function ...
     END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;

   The disadvantage of this is that if the foreign code allocates any
memory internally, then this memory might be lost during an interrupt,
without being deallocated.  Therefore, ideally Octave itself should
allocate any memory that is needed by the foreign code, with either the
‘fortran_vec’ method or the ‘OCTAVE_LOCAL_BUFFER’ macro.

   The Octave ‘unwind_protect’ mechanism (Note: The unwind_protect
Statement) can also be used in oct-files.  In conjunction with the
exception handling of Octave, it ensures that certain recovery code is
always run even if an exception occurs.  An example of the use of this
mechanism is

     #include <octave/oct.h>
     #include <octave/unwind-prot.h>
     
     void
     my_err_handler (const char *fmt, ...)
     {
       // Do nothing!!
     }
     
     void
     my_err_with_id_handler (const char *id, const char *fmt, ...)
     {
       // Do nothing!!
     }
     
     DEFUN_DLD (unwinddemo, args, nargout, "Unwind Demo")
     {
       if (args.length () < 2)
         print_usage ();
     
       NDArray a = args(0).array_value ();
       NDArray b = args(1).array_value ();
     
       // Declare unwind_protect frame which lasts as long as
       // the variable frame has scope.
       octave::unwind_protect frame;
       frame.add_fcn (set_liboctave_warning_handler,
                      current_liboctave_warning_handler);
     
       frame.add_fcn (set_liboctave_warning_with_id_handler,
                      current_liboctave_warning_with_id_handler);
     
       set_liboctave_warning_handler (my_err_handler);
       set_liboctave_warning_with_id_handler (my_err_with_id_handler);
     
       return octave_value (quotient (a, b));
     }

   As can be seen in the example:

     unwinddemo (1, 0)
     ⇒ Inf
     1 / 0
     ⇒ warning: division by zero
        Inf

   The warning for division by zero (and in fact all warnings) are
disabled in the ‘unwinddemo’ function.


automatically generated by info2www version 1.2.2.9