Maskowanie wyjątków zmiennoprzecinkowych za pomocą Set8087CW, SetMXCSR i TWebBrowser
Ponieważ otrzymuję wyjątek „Podział zmiennoprzecinkowy przez zero” podczas używania TWebBrowser i TEmbeddedWB od czasu do czasu, odkryłem, że muszę maskować podział przez zero wyjątków Set8087CW lub SetMXCSR.
P1: Jakie byłoby najlepsze podejście, aby to zrobić:
maskować takie wyjątki na początku uruchamiania aplikacji i nigdy ich nie dotykać (aplikacja jest wielowątkowa)?używaćOnBeforeNavigate
iOnDocumentComplete
zdarzenia do maskowania / demaskowania wyjątków? (czy istnieje szansa, że wyjątek może wystąpić po załadowaniu dokumentu?)P2: Jaka byłaby najlepsza „komenda” maskująca tylko „dzielenie przez zero” i nic innego - jeśli aplikacja jest 32-bitowa, czy istnieje potrzeba maskowania 64-bitowego wyjątku?
Aplikacja, z której korzystam, ma kontrolę TWebBrowser przez cały czas do wyświetlania treści e-mail.
Ponadto, jeśli ktoś może wyjaśnić - czy jest to szczególny błąd z kontrolą TWebBrowser od Microsoft, czy po prostu różnica między Delphi / C ++ Builder a narzędziami Microsoft? Co by się stało, gdybym hostował TWebBrowser wewnątrz aplikacji Visual C ++, gdyby pojawił się błąd dzielenia przez zero - nie byłoby to tłumaczone na wyjątek, ale co by się wtedy stało - jak wtedy Visual C ++ obsługiwałby wyjątek „dzielenie przez zero”?
To dziwne, że Microsoft nie zauważył tego problemu przez tak długi czas - również dziwne, że Embarcardero też tego nie zauważył. Ponieważ maskowanie wyjątków zmiennoprzecinkowych skutecznie maskuje także wyjątek twojego programu w tym konkretnym celu.
AKTUALIZACJA
Moje ostateczne rozwiązanie po pewnym badaniu to:
SetExceptionMask(GetExceptionMask() << exZeroDivide);
Stan domyślny zGetExceptionMask () zwraca:TFPUExceptionMask() << exDenormalized << exUnderflow << exPrecision
. Oczywiście, niektóre wyjątki są już zamaskowane - to po prostu dodajeexZeroDivide
do zamaskowanych wyjątków.
W rezultacie każdy podział przez zero jest teraz wynikiem+ INF w zmiennoprzecinkowym zamiast wyjątku. Mogę z tym żyć - dla wersji produkcyjnej kodu zamaskuje mnie, aby uniknąć błędów, a dla wersji debugowania zostanie zdemaskowany, aby wykryć podział zmiennoprzecinkowy przez zero.