try-finally 语句

try-finally 语句是一个 特定于Microsoft的 扩展,支持 C 和 C++ 语言中的结构化异常处理。

语法

以下语法描述了 try-finally 该语句:

    // . . .
    __try {
        // guarded code
    }
    __finally {
        // termination code
    }
    // . . .

语法

try-finally-statement:
__try compound-statement __finally compound-statement

try-finally 语句是 C 和 C++ 语言的Microsoft扩展,使目标应用程序能够保证在代码块执行中断时执行清理代码。 清理包括解除分配内存、关闭文件和释放文件句柄等任务。 该 try-finally 语句对于具有多个位置的例程特别有用,这些例程检查了可能导致例程过早返回的错误。

有关相关信息和代码示例,请参阅 try-except 语句。 有关结构化异常处理的详细信息,请参阅 结构化异常处理。 有关使用 C++/CLI 在托管应用程序中处理异常的详细信息,请参阅下面的/clr异常处理

注释

结构化异常处理适用于 C 和C++源文件的 Win32。 但是,它不是专门为C++设计的。 可以使用C++异常处理来确保代码更易于移植。 此外,C++异常处理更灵活,因为它可以处理任何类型的异常。 对于C++程序,建议使用C++异常处理机制(trycatchthrow语句)。

子句后面的 __try 复合语句是受保护的节。 子句后面的 __finally 复合语句是终止处理程序。 处理程序指定在退出受保护的节时执行的一组作,无论是通过异常(异常终止)还是标准终止(正常终止)退出受保护的节。

通过简单的顺序执行(倒入)控制到达 __try 语句。 当控件进入控件 __try时,其关联的处理程序将变为活动状态。 如果控制流到达 try 块的末尾,则执行将按如下方式继续:

  1. 调用终止处理程序。

  2. 终止处理程序完成后,执行将继续在 __finally 语句之后执行。 但是,受保护的节结束(例如,通过 goto 受保护的正文或 return 语句),终止处理程序在控制流移出受保护的节 之前 执行。

    语句 __finally 不会阻止搜索适当的异常处理程序。

如果在块中 __try 发生异常,作系统必须找到异常的处理程序,否则程序将失败。 如果找到处理程序,则会执行所有 __finally 块,并在处理程序中恢复执行。

例如,假设一系列函数调用将函数 A 链接到函数 D,如下图所示。 每个函数都有一个终止处理程序。 如果在函数 D 中引发并在 A 中处理异常,则会按此顺序调用终止处理程序,因为系统展开堆栈:D、C、B。

终止处理程序执行顺序的关系图。

该关系图以函数 A 开头,该函数调用函数 B,后者调用函数 C,后者调用函数 D。函数 D 引发异常。 然后按以下顺序调用终止处理程序:D 的终止处理程序、C 的、B 的,然后 A 处理异常。

终止处理程序执行的顺序

注释

try-finally 的行为不同于支持使用 finally的其他一些语言,例如 C# 。 一个可能 __try 具有两者,但不能同时 __finally 具有和 __except。 如果两者一起使用在一起,则外部 try-except 语句必须包含内部 try-finally 语句。 指定每个块执行时间的规则也不同。

为了与以前的版本、_try_leave_finally同义词兼容__try__finally__leave除非指定编译器选项/Za(禁用语言扩展)。

__leave 关键字

关键字 __leave 仅在语句的 try-finally 受保护的节内有效,其效果是跳转到受保护的节的末尾。 在终止处理程序的第一个语句处继续执行。

语句 goto 也可以跳出受保护的节,但它会降低性能,因为它调用堆栈展开。 该 __leave 语句更高效,因为它不会导致堆栈展开。

异常终止

try-finally使用 longjmp 运行时函数退出语句被视为异常终止。 跳入一 __try 份声明是不合法的,但从一份声明中跳出来是合法的。 必须在出发点(块的正常终止__try)和处理异常的块(__except处理异常的块)之间处于活动状态的所有__finally语句。 它称为 本地展开

__try如果由于任何原因(包括跳出块)而过早终止块,则系统将执行关联的__finally块作为展开堆栈过程的一部分。 在这种情况下,如果从块内部__finally调用,则AbnormalTermination函数返回true;否则返回 false

如果在执行 try-finally 语句的过程中终止进程,则不会调用终止处理程序。

特定于 END Microsoft

另请参阅

编写终止处理程序
结构化异常处理 (C/C++)
关键字
终止处理程序语法