try-finally ステートメントtry-finally Statement

Microsoft 固有の仕様Microsoft Specific

次の構文では、 try finallyステートメントについて説明します。The following syntax describes the try-finally statement:

_ _try__try
       //保護されたコード    // guarded code
_ _finally__finally
       //終了コード    // termination code


        _ _try 複合ステートメント _ 0finally 複合ステートメント    __try compound-statement __finally compound-statement

Try-catchステートメントは、コードのブロックの実行が中断されC++た場合に、対象アプリケーションがクリーンアップコードの実行を保証できるようにする、C および言語に対する Microsoft の拡張機能です。The try-finally statement is a Microsoft extension to the C and C++ languages that enables target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. クリーンアップは、メモリを解放する、ファイルを閉じる、ファイル ハンドルを解放するなどのタスクで構成されます。Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. Try-catchステートメントは、ルーチンからの予期しない戻りが発生する可能性があるエラーに対してチェックが行われる複数の場所を持つルーチンで特に便利です。The try-finally statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine.

関連情報とコードサンプルについては、「 try-Except ステートメント」を参照してください。For related information and a code sample, see try-except Statement. 構造化例外処理全般の詳細については、「構造化例外処理」を参照してください。For more information on structured exception handling in general, see Structured Exception Handling. /Cli を使用したC++マネージアプリケーションでの例外処理の詳細については、「 /Clr での例外処理」を参照してください。For more information on handling exceptions in managed applications with C++/CLI, see Exception Handling under /clr.


構造化例外処理では、C と C++ のソース ファイルの両方で Win32 を使用します。Structured exception handling works with Win32 for both C and C++ source files. ただし、特に C++ 用にデザインされたものではありません。However, it is not specifically designed for C++. C++ 例外処理を使用して、コードの移植性を高めることができます。You can ensure that your code is more portable by using C++ exception handling. また、C++ 例外処理は、任意の型の例外を処理できるという点で、より柔軟です。Also, C++ exception handling is more flexible, in that it can handle exceptions of any type. プログラムC++については、 C++例外処理機構 (try、catch、および throwステートメント) を使用することをお勧めします。For C++ programs, it is recommended that you use the C++ exception-handling mechanism (try, catch, and throw statements).

__Try句の後の複合ステートメントは、保護されたセクションです。The compound statement after the __try clause is the guarded section. __Finally句の後の複合ステートメントは、終了ハンドラーです。The compound statement after the __finally clause is the termination handler. ハンドラーは、保護されたセクションが例外によって終了 (異常終了) したか、標準的なフォール スルー (正常終了) で終了したかにかかわらず、保護されたセクションが終了したときに実行する一連の操作を指定します。The handler specifies a set of actions that execute when the guarded section is exited, regardless of whether the guarded section is exited by an exception (abnormal termination), or by standard fall through (normal termination).

制御は、単純な順次実行 (フォールスルー) によって、 __tryステートメントに到達します。Control reaches a __try statement by simple sequential execution (fall through). コントロールが __tryに入ると、関連付けられているハンドラーがアクティブになります。When control enters the __try, its associated handler becomes active. 制御のフローが try ブロックの終わりに到達すると、次のように実行は処理されます。If the flow of control reaches the end of the try block, execution proceeds as follows:

  1. 終了ハンドラーが呼び出されます。The termination handler is invoked.

  2. 終了ハンドラーが完了すると、 __finallyステートメントの後に実行が継続されます。When the termination handler completes, execution continues after the __finally statement. 保護されたセクションがどのように終了するかに関係なく (たとえば、保護された本体またはreturnステートメントからのgotoを使用して)、制御フローが保護されたセクションから移動する前に終了ハンドラーが実行されます。Regardless of how the guarded section ends (for example, via a goto out of the guarded body or a return statement), the termination handler is executed before the flow of control moves out of the guarded section.

    __Finallyステートメントは、適切な例外ハンドラーの検索をブロックしません。A __finally statement does not block searching for an appropriate exception handler.

__Tryブロックで例外が発生した場合、オペレーティングシステムは例外のハンドラーを見つける必要があります。見つからない場合、プログラムは失敗します。If an exception occurs in the __try block, the operating system must find a handler for the exception or the program will fail. ハンドラーが見つかった場合は、すべての __finallyブロックが実行され、ハンドラーで実行が再開されます。If a handler is found, any and all __finally blocks are executed and execution resumes in the handler.

たとえば、次の図に示すように、一連の関数呼び出しで、関数 A を関数 D にリンクするとします。For example, suppose a series of function calls links function A to function D, as shown in the following figure. 各関数には、1 つの終了ハンドラーがあります。Each function has one termination handler. 関数 D で例外が発生し、A で処理されると、スタックがアンワインドされるときに、終了ハンドラーは D、C、B の順に呼び出されます。If an exception is raised in function D and handled in A, the termination handlers are called in this order as the system unwinds the stack: D, C, B.

終了-ハンドラーの実行順序Order of termination-handler execution
終了順序 - ハンドラーの実行Order of Termination-Handler Execution


Try-finally の動作は、など、 finallyの使用をサポートする他の言語とC#は異なります。The behavior of try-finally is different from some other languages that support the use of finally, such as C#. 1つの __tryには、 __finally__exceptのどちらか一方だけを含めることができます。A single __try may have either, but not both, of __finally and __except. 両方を一緒に使用する場合は、外側の try-except ステートメントで内側の try-finally ステートメントを囲む必要があります。If both are to be used together, an outer try-except statement must enclose the inner try-finally statement. 各ブロックがいつ実行されるかを指定する規則も異なります。The rules specifying when each block executes are also different.

以前のバージョンとの互換性を維持するには、コンパイラオプション/za (Disable 言語拡張機能を除く) が、 __try__finally、および __ のシノニムであることを確認てください。指定した.For compatibility with previous versions, _try, _finally, and _leave are synonyms for __try, __finally, and __leave unless compiler option /Za (Disable language extensions) is specified.

__leave キーワードThe __leave Keyword

__ Leaveキーワードは、 try-catchステートメントの保護されたセクション内でのみ有効です。その結果、保護されたセクションの末尾に移動します。The __leave keyword is valid only within the guarded section of a try-finally statement, and its effect is to jump to the end of the guarded section. 実行は、終了ハンドラーの最初のステートメントに移って続行されます。Execution continues at the first statement in the termination handler.

Gotoステートメントは、保護されたセクションからジャンプすることもできますが、スタックアンワインドを呼び出すため、パフォーマンスが低下します。A goto statement can also jump out of the guarded section, but it degrades performance because it invokes stack unwinding. __ Leaveステートメントは、スタックアンワインドが発生しないため、より効率的です。The __leave statement is more efficient because it does not cause stack unwinding.

異常終了Abnormal Termination

Longjmpランタイム関数を使用して、 finallyステートメントを終了すると、異常終了と見なされます。Exiting a try-finally statement using the longjmp run-time function is considered abnormal termination. __Tryステートメントにジャンプすることはできませんが、1つから除外することはできません。It is illegal to jump into a __try statement, but legal to jump out of one. 出発点 ( __tryブロックの通常の終了) と変換先 (例外を処理する __exceptブロック) の間でアクティブなすべての __finallyステートメントを実行する必要があります。All __finally statements that are active between the point of departure (normal termination of the __try block) and the destination (the __except block that handles the exception) must be run. これは、ローカル アンワインドと呼ばれます。This is called a local unwind.

Tryブロックが、ブロックからのジャンプを含め、何らかの理由で途中で終了した場合、スタックをアンワインドするプロセスの一部として、関連付けられているfinallyブロックが実行されます。If a try block is prematurely terminated for any reason, including a jump out of the block, the system executes the associated finally block as a part of the process of unwinding the stack. このような場合、 Abnormaltermination関数は、 finallyブロック内から呼び出されるとtrueを返します。それ以外の場合はfalseを返します。In such cases, the AbnormalTermination function returns true if called from within the finally block; otherwise, it returns false.

Finallyステートメントの実行中にプロセスが強制終了した場合、終了ハンドラーは呼び出されません。The termination handler is not called if a process is killed in the middle of executing a try-finally statement.

Microsoft 固有の仕様はここまでEND Microsoft Specific

関連項目See also

終了ハンドラーの記述Writing a Termination Handler
構造化例外処理 (C/C++)Structured Exception Handling (C/C++)
終了ハンドラーの構文Termination-Handler Syntax