Ada 83 异常是否包括资源清理?

Do Ada 83 exceptions include resource cleanup?

Ada 83 是最早出现异常的语言之一。 (我想说 'the first',但我从研究技术史中学到的一件事是,几乎总是有一个更早的 X。)

从实现的角度来看,实现异常最复杂的部分是它们与资源清理的交互(C++ 中的析构函数,Java 中的 try-finally 等);当抛出异常时,资源清理代码需要在退出每个动态嵌套范围时 运行。

Ada 83 是否有任何异常调用的资源清理功能?还是可以直接执行 longjmp?

允许在引发异常之前执行资源清理作为一个步骤,但 Ada 83 异常不会自动清理资源。异常如何知道哪些资源需要清理,哪些不应该清理?可以在同一个块中引发和处理异常处理程序,在这种情况下,程序员可以清理处理程序中的相关资源,或者可以将其传播到封闭块或范围内调用引发异常的子程序的块. Ada 83 异常在语义上没有连接到一组需要清理的资源。

异常通常是在引发异常的范围之外声明的。如果不是这样,则无法在按名称声明的范围之外显式处理异常,只能使用异常处理程序中的其他选项来处理。

问题不在于异常是否真正清理资源,而是离开 声明范围,例如子程序主体或块语句,是否清理在该范围内分配的资源.离开范围的原因是次要问题。执行是通过到达范围的“末端”还是通过传播在范围内引发但未在范围内处理的异常而离开都没有多大关系。

Ada 83 对“资源”的概念非常有限,但确实会尝试清理这些资源。当一个作用域离开时,堆栈帧和该作用域的所有局部变量都会被删除。如果作用域声明了一个本地访问类型,尤其是声明中有一个 Storage_Size 子句,则当作用域离开时,该访问类型的动态分配对象的整个“集合”可能会被删除(释放,释放)(虽然我认为这不是一个严格的要求,有些编译器可能没有实现它)。如果范围是某些任务的主人(“所有者”),则任务必须在离开范围之前终止(但程序员负责以某种方式通知任务它们应该终止,或中止任务)。

但是对于今天被认为是“资源”的大部分内容,例如具有 non-local 访问类型的本地堆分配、打开本地声明的文件等,Ada 83 不会自动清理此类本地资源离开本地范围时分配。正常的习惯用法是这样的范围有一个本地异常处理程序来清理资源,然后(如果需要)re-raises 异常或引发另一个异常。