● 例外処理

_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){

            スタックフォルト等、比較的低い水準の例外を処理

    }