A.1.12 Oct文件中的异常和错误处理

Octave的另一个重要函数是它能够对用户输入的内容做出反应Control-C在扩展计算期间。此函数基于C++异常处理程序,在处理异常时,从C++新/删除方法赋值的内存会自动释放。当编写可能长时间运行的oct文件时,程序员必须定期使用宏OCTAVE_QUIT ,以允许Octave检查并可能响应用户输入Control-C例如

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

的存在OCTAVE_QUIT 内部循环中的宏允许Ocve检测并确认Control-C密钥序列。如果没有此宏,用户必须等待oct文件函数返回后才能处理中断,或者用户必须按Control-C三次,这将迫使Octave完全退出。

这个OCTAVE_QUIT 宏确支持加了非常小的性能惩罚;对于已知很小的循环,包含可能没有意义OCTAVE_QUIT .

当创建使用外部库的oct文件时,函数可能会在外部库中花费大量时间。通常不可能使用OCTAVE_QUIT 宏。本例中的备用代码是

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

这样做的缺点是,如果外部代码在内部赋值任何内存,那么这些内存可能会在中断期间丢失,而不会被赋值。因此,理想情况下,Octave本身应该赋值外部代码所需的任何内存,使用fortran_vec方法或OCTAVE_LOCAL_BUFFER 宏。

octaveunwind_protect机械装置The unwind_protect Statement)也可以在oct文件中使用。结合Octave的异常处理,它可以确保某些恢复代码始终运行,即使发生异常。使用此机制的一个示例是

#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 ();

  // Create unwind_action objects.  At the end of the enclosing scope,
  // destructors for these objects will call the given functions with
  // the specified arguments.

  octave::unwind_action restore_warning_handler
    (set_liboctave_warning_handler, current_liboctave_warning_handler);

  octave::unwind_action restore_warning_with_id_handler
    (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));
}

从示例中可以看出:

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

中禁用了除以零的警告(实际上是所有警告)unwinddemo作用


版权所有 © 2024-2025 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-2