浮動小数点例外を処理する (/fpe) コンパイラ・オプションの動作内容

基本ハンドラが浮動小数点例外を重大 (severe) または非重大のどちらで処理するかは,/fpe および /check:underflow コンパイラ・オプションの選択に依存します。/fpe オプションは,基本例外ハンドラの動作以上を制御します。

/fpe オプションは,特定の浮動小数点例外動作を選択します。ia32 システムに対して,現在,サポートする動作が 2 つあります。

/fpe コンパイラ・オプションの完全な結果は,ビルドするアプリケーションのタイプに依存します。基本実行時例外ハンドラを置き換えてないと仮定すると,Fortran Console または QuickWin/Standard Graphics アプリケーションでの選択した動作に対して完全なサポートを得られます。完全な動作を実行するための作業は,基本実行時ハンドラ,Fortran コンパイラ,算術ライブラリー,ハードウェア,およびオペレーティング・システムの各々が部分的に実行します。

以下の内容について説明します。

Fortran Console,Fortran QuickWin,および Fortran Standard Graphics アプリケーションでの浮動小数点例外

Fortran Console アプリケーションをビルドする時,基本コンパイラ・オプションまたは選択したコンパイラ・オプションのどちらかで環境を初期化するFortran 実行時ルーチンを呼び出す幾つかの呼び出しを,コンパイラは Fortran 主プログラムの先頭に生成します。

アンダーフロー結果をゼロに修正することは,ia32 アプリケーションの性能を著しく低下させます。アンダーフローが頻繁に発生する場合,アンダーフローが発生しないようにコードを変更する,または,アンダーフロー・とラップをマスクし,規格化されない数字をハードウェアが操作できるようにすることを考慮してください。ia32 ハードウェアは,規格化されない範囲で正しく動作するように設計されており,そのようにすることは結果をゼロに修正するためのトラップを行うことよりも高速になります。

/fpe オプションの選択について理解することの他の重要な点は,生成されたコードがトラッピング・モードをサポートしなければならないことです。ia32 浮動小数点命令が例外結果を生成する時,トラップを得る必要はありません。命令は,トラップを発生させるようにするために,fwait 命令または浮動小数点演算命令に従わなければなりません。

Visual Fortran コンパイラは,/fpe オプションの選択に関連するこれらの要求をサポートするための機械語コードを生成します。言い換えれば,生成されたコードは,トラッピング・モードをサポートしなえればなりません。簡単なテスト・プログラムをコンパイルすることで,これを見ることができます。まず,/fpe:0 で,次に /fpe:3 でコンパイルして機械語コード・リストを調べます。/fpe:3 では,fwait 命令がありません。自分独自のハンドラで基本実行時例外ハンドラを置き換えた場合でも,トラッピングをサポートするコードを生成するために,/fpe:0 でコンパイルすることもできます。

Fortran DLL アプリケーションでの浮動小数点例外

DLL では,(Fortran で主プログラムを書かなければ) 主 Fortran プログラムがありません。そのため,環境を初期化する実行時ルーチンの自動呼出しがありません。/fpe:0 を選択したとしても,実行時システムにハードウェアでのトラップをアンマスクさせることはありません。そのため,トラップを見ることができません。ハードウェアが生成する基本 IEEE 結果 (計算での NaN, 無限大,規格化されていない数字) を見つづけることになります。生成されたコードは,fwait 命令などを提供することで部分的に行いますが,トラップがどこかでアンマスクされない限り,トラップは発生しません。浮動小数点コントロール・ワードでトラップをアンマスクするために SETCONTROLFPQQ または FOR_SET_FPE を使用することができます。

DLL では,基本例外処理もありません。DLL を呼び出す主アプリケーションがこれを提供するか,DLL のコードがそれが呼び出される時に何かを提供しなければなりません。アンダーフロー処理 (0 に修正など) が基本 Fortran 実行時システム・ハンドラで行われるため,DLL は自動的にはその機能を持っていません。

一般的なやり方としては,/fpe:0 でコンパイルします。しかし,浮動小数点コントロール・ワードの浮動小数点のゼロによる除算,浮動小数点オーバーフロー,および浮動小数点の不正確な値のトラップのみをアンマスクします。浮動小数点アンダーフロー・トラップをマスクしたままにしておくことによって,ハードウェアは規格化されない範囲を通して漸進的なアンダーフローを提供しつづけます。しかし他の浮動小数点例外は,トラップを生成するので,ユーザーは希望に応じて処理することができます。

Fortran Windows アプリケーションでの浮動小数点例外

Fortran Windows アプリケーションでは,状況は Fortran DLL アプリケーションに似ています。アプリケーションの主エントリ・ポイントとして Fortran コードに WinMain ルーチンを定義します。Fortran 実行時システムは,Fortran Console または Fortran QuickWin (または Standard Graphics) アプリケーションで行ったような主ルーチンを定義しません。コードは,基本ハンドラで保護されませんし,基本実行時初期化ルーチンは呼び出されません。