多くの数学的計算を実行する C++ の Visual Studio 2012/13 に組み込まれた MFC 製品があります。コプロセッサを介して浮動小数点割り込みを使用して、try/catch ブロックを設定することで計算を高速化します。これらの割り込みは Windows 7 ではうまく機能しますが、Windows 10 の更新プログラムの 1 つがシーケンスを壊しました。「シグナル」呼び出しは「ハンドラー」コールバックの正しいポインターをセットアップしますが、Windows 10 はそれを無視します。(同じコードがコンソール プログラムで機能します。MFC コードでのみ失敗します。最も単純なコードを取り除いた例でも)。SEH を使用した回避策がありますが、この問題が発生した理由を知りたいと考えています。情報をありがとう。
関連するコードは、ハンドラーが FloatException をスローする場所です (Windows 10 では割り込みがハンドラーに到達しないことに注意してください)。
_clearfp();
_controlfp_s(0, _EM_INEXACT, _MCW_EM);
signal(SIGFPE, (fptr)HandleMathError);
try
{
...calculate
}
catch (FloatException &e)
{
...recover
_fpreset();
_clearfp();
_controlfp_s(0, old_control_word, _MCW_EM);
signal(SIGFPE, SIG_DFL);
return;
}
完全を期すために、MFC の失敗を確認するには、必要なコードに少なくとも 9 個のファイルが必要です。まず、単一ドキュメント、ドキュメント/ビュー、mfc 標準インターフェイス、スタティック ライブラリ、複合ドキュメントなし、データベースなし、クラシック メニューを使用して、単純な MFC アプリケーションを生成します。次に、MainFrm::OnCreate で、上記の割り込みコードを「raise(SIGFPE)」のみの計算として挿入します。「HandleMathError」と「Float Exception」の定義を次のように追加します。
typedef void( *fptr )( int );
void __cdecl HandleMathError( int sig, int subcode );
class FloatException : public std::exception
{
public:
FloatException( int _foo )
{
foo = _foo;
}
int foo;
};
void __cdecl HandleMathError( int sig, int subcode )
{
throw FloatException( subcode );
return;
}
このコードでは、Windows 7 では割り込みハンドラーが入力され、Windows 10 では入力されません。シグナルを使用して存在するハンドラーのテストは、両方の OS で肯定的です。Windows 10 はハンドラーを無視しています。