Dealing with Floating-point Exceptions in MSVC7\8 : Page 4
Learn how to catch floating-point exceptions in C\C++ code.
by Boris Eligulashvili
Jul 13, 2007
Page 4 of 4
The Visual Studio Compiler Options
For both Debug and Release configurations, Visual Studio offers the "Code Generation" property page in "C/C++" property folder. Here, you can select the desired option for the "Enable Enhanced Instruction Set" property. The available options are:
"Streaming SIMD Extensions (/arch:SSE):" The new set of instructions and registers on the Pentium III processor allows Single-Instruction Multiple-Data (SIMD) computations to be made on single-precision floating-point numbers. You may see the assembler code for both options above in a disassembly window during debugging that looks like:
Because the assembly code is the same for both options, no changes are needed for the source code in order to trap floating-point exceptions when the option is set to /arch:SSE.
"Streaming SIMD Extensions 2 (/arch:SSE2)": The new set of instructions on the Pentium 4 and Intel Xeon processors operates on the XXM and MXCSR registers and performs SIMD computations on double-precision floating-point and integer numbers. The assembler code for this option looks like:
The SSE and SSE2 instructions can generate the same floating-point exceptions (mentioned above) that are generated with x87 floating-point instructions and are defined in IEEE Standard 754. There is also a Denormal operand exception that is not defined in the standard. Each of the exception conditions has a corresponding flag and mask in the MXCSR register. Control register CR4's OSXMMEXCEPT flag provides additional control over generation of SIMD floating-point exceptions.
Comparing VS 2005 with VS 2003
VS 2005 introduced some improvements in dealing with floating-point exceptions. To compare with VS 2003:
The options for the Code Generation \Enable C++ Exceptions property in VS2003 are:
No: Structured and C++ exceptions are captured, but C++ objects that go out –f-scope as a result of exception will not be destroyed. This is an equivalent to /EHsc-.
Yes (/EHsc): Only C++ exceptions will be captured. This means that catch(. . .) will not catch C exceptions. The C++ objects that should be destroyed will be destroyed. During optimization, the Release configuration compiler may optimize away the catch clause if it does not see a throw nside the try block.
Changes for VS2005:
Yes (/EHsc): If a C exception is generated, the C++ objects that should be destroyed will not be destroyed. This means that C++ exception handling works correctly only for C++ exceptions; in other words, catch (. . .) does not catch C exceptions.
Yes with SHE Exceptions (/EHa) catch (. . .) will catch C and C++ exceptions. Also, if you install a translator function, this option should be selected.
The options for Code Generation\Enable Floating Point Exceptions property (Enable Floating Point Exception Semantics) in VS 2005 are:
No: Turned off.
Yes (/fp:except): The compiler introduces a WAIT instruction after each floating-point instruction. This forces the processor to synchronize with the state of the FPU and handle any pending exceptions. Also, this prevents the compiler from illegally optimizing floating-point code.
In addition to this option, which is used on a file-by-file basis, you can control the same floating-point semantic on a function-by-function basis by using the float_control pragma directive. For example:
#pragma float_control (except, off | on)
This option is not compatible with /arch:SSE.
The options for “Optimization\Floating-Point Consistency” property in VS2003 are:
Default Consistency: The compiler uses processor's 80 bit registers to hold the intermediate results of floating-point calculations.
Improved Consistency (/Op): The compiler loads data from memory prior to each floating-point operation (optimization is disabled).
Changes for VS2005:
This property has been removed. The new property is Code Generation\Floating Point Model with these options:
Precise (fp:precise): Replaces the /Ops option.
Strict (/fp:strict): Creates the strictest code.
Fast (/fp:fast): The compiler creates the fastest code in the majority of cases.
If you use _controlfp() in code compiled with VS 2005, you will get a C4996 warning that this function has been deprecated. Use _controlfp_s() instead.
Boris Eligulashvili is a Senior Engineer at Viewray, Inc. Prior to joining Viewray, he worked his way through different software development positions for Allen-Bradley, Saint-Gobain Crystals and Detectors, Philips Medical Systems, and Hitachi Medical Systems America, Inc. He has worked with the latest technologies as they have evolved throughout the yearsfrom raw machine code to .NET. His current focus is in developing software solutions for a novel MRI-guided radiotherapy device.