● 例外処理
_fpieee_flt によるユーザ定義ハンドラ
関数 _fpieee_flt(fpieee.h)を使用すると、__try 〜 __except だけよりも高水準な処理にする事ができます。
テスト.
#include <stdio.h>
#include <fpieee.h>
#include <excpt.h>
#include "floatex.h"
/* ユーザ定義の例外ハンドラ */
int __cdecl fpieee_handler(_FPIEEE_RECORD *pieee)
{
/* ゼロ除算で、例外を起こした演算が 80bit フォーマットの場合 */
if ((pieee->Cause.ZeroDivide) && (pieee->Result.Format == _FpFormatFp80))
printf("80 bit 精度 ゼロ除算例外\n");
return EXCEPTION_EXECUTE_HANDLER;
}
void __cdecl main(void)
{
FLOATEX val;
unsigned int oldcw;
floatex_clear87();
oldcw = floatex_storecw();
floatex_loadcw(
FEX_PC_64 | FEX_RC_NEAR | FEX_EM_INEXACT); /* 不正確結果以外の例外を有効にする */
__try{
floatex_doubleto(4095.0,val);
floatex_div(val,fex_const_0); /* ゼロ除算例外を発生させる */
}
__except(_fpieee_flt(
GetExceptionCode(),
GetExceptionInformation(),
fpieee_handler)){
printf("exception\n");
}
floatex_loadcw(oldcw);
}
関数_fpieee_flt 、構造体、定数の詳細は、コンパイラのマニュアル及び fpieee.h を参照してください。
_fpieee_flt を使用すると、関数が浮動小数点例外の情報を _FPIEEE_RECORD 構造体にまとめるので、プログラム側が情報収集を行う手間が省けます。また、_fpieee_flt 実行後は例外フラグがクリアされるので、ハンドラ内で floatex.dll の関数を自由に使用する事ができます。適用するプログラムの状況にもよりますが、演算に関する例外処理は、_fpieee_flt を使用した方が簡単にする事ができるかもしれません。
_fpieee_flt による例外処理機構はスタックフォルトをキャッチしません。スタックフォルトも処理する必要がある場合は、次のように __try 〜 __except を入れ子にする必要があります。
構成例.
__try{
__try{
演算処理
}
__except(_fpieee_flt(
GetExceptionCode(),
GetExceptionInformation(),
ユーザ定義ハンドラ)){
演算に関する例外等、比較的高い水準の例外を処理
}
}
__except(
(浮動小数点例外の場合)? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH){
スタックフォルト等、比較的低い水準の例外を処理
}