Skip to content

Latest commit

 

History

History
158 lines (111 loc) · 6.74 KB

float-control.md

File metadata and controls

158 lines (111 loc) · 6.74 KB
titledescriptionms.datef1_keywordshelpviewer_keywordsno-loc
float_control pragma
Describes the usage and effects of the float_control pragma directive. The float_control directive controls the state of floating-point precise semantics and exception semantics at runtime.
08/10/2021
vc-pragma.float_control
float_control_CPP
float_control pragma
pragma, float_control
pragma

float_control pragma

Specifies floating-point behavior for a function.

Syntax

#pragma float_control
#pragma float_control( precise, { on | off } [ , push ] )
#pragma float_control( except, { on | off } [ , push ] )
#pragma float_control( { push | pop } )

Options

precise, on | off, push
Specifies whether to enable (on) or disable (off) precise floating-point semantics. For information on differences with the /fp:precise compiler option, see the Remarks section. The optional push token pushes the current setting for float_control on the internal compiler stack.

except, on | off, push
Specifies whether to enable (on) or disable (off) floating-point exception semantics. The optional push token pushes the current setting for float_control on the internal compiler stack.

except can only be set to on when precise is also set to on.

push
Pushes the current float_control setting on to the internal compiler stack.

pop
Removes the float_control setting from the top of the internal compiler stack, and makes that the new float_control setting.

Remarks

The float_control pragma doesn't have the same behavior as the /fp compiler option. The float_control pragma only governs part of the floating-point behavior. It must be combined with fp_contract and fenv_access pragma directives to recreate the /fp compiler options. The following table shows the equivalent pragma settings for each compiler option:

::: moniker range=">msvc-160"

Optionfloat_control(precise, *)float_control(except, *)fp_contract(*)fenv_access(*)
/fp:strictononoffon
/fp:preciseonoffoff*off
/fp:fastoffoffonoff

* In versions of Visual Studio before Visual Studio 2022, the /fp:precise behavior defaulted to fp_contract(on).

::: moniker-end ::: moniker range="<=msvc-160"

Optionfloat_control(precise, *)float_control(except, *)fp_contract(*)fenv_access(*)
/fp:strictononoffon
/fp:preciseonoffoffoff
/fp:fastoffoffonoff

::: moniker-end

In other words, you may need to use several pragma directives in combination to emulate the /fp:fast, /fp:precise, and /fp:strict command-line options.

There are restrictions on the ways you can use the float_control and fenv_access floating-point pragma directives in combination:

  • You can only use float_control to set except to on if precise semantics are enabled. Precise semantics can be enabled either by the float_control pragma, or by using the /fp:precise or /fp:strict compiler options.

  • You can't use float_control to turn off precise when exception semantics are enabled, whether by a float_control pragma or a /fp:except compiler option.

  • You can't enable fenv_access unless precise semantics are enabled, whether by a float_control pragma or a compiler option.

  • You can't use float_control to turn off precise when fenv_access is enabled.

These restrictions mean the order of some floating-point pragma directives is significant. To go from a fast model to a strict model using pragma directives, use the following code:

::: moniker range=">msvc-160"

#pragma float_control(precise, on) // enable precise semantics #pragma fenv_access(on) // enable environment sensitivity #pragma float_control(except, on) // enable exception semantics

::: moniker-end ::: moniker range="<=msvc-160"

#pragma float_control(precise, on) // enable precise semantics #pragma fenv_access(on) // enable environment sensitivity #pragma float_control(except, on) // enable exception semantics #pragma fp_contract(off) // disable contractions

::: moniker-end

To go from a strict model to a fast model by using the float_control pragma, use the following code:

#pragma float_control(except, off) // disable exception semantics #pragma fenv_access(off) // disable environment sensitivity #pragma float_control(precise, off) // disable precise semantics #pragma fp_contract(on) // enable contractions

If no options are specified, float_control has no effect.

::: moniker range=">msvc-160"

The float_control directive disables contractions when it turns on precise or except. Use of float_control to turn off precise or except restores the previous setting for contractions. You can use the fp_contract pragma directive to change the compiler behavior on contractions. float_control(push) and float_control(pop) push and pop the setting for contractions as part of the float_control setting on to the internal compiler stack. This behavior is new in Visual Studio 2022. The float_control directive in previous compiler versions did not affect contraction settings.

::: moniker-end

Example

The following sample shows how to catch an overflow floating-point exception by using pragma float_control.

// pragma_directive_float_control.cpp// compile with: /EHa #include<stdio.h> #include<float.h>doublefunc( ) { return1.1e75; } #pragma float_control (except, on) intmain( ) { float u[1]; unsignedint currentControl; errno_t err; err = _controlfp_s(&currentControl, ~_EM_OVERFLOW, _MCW_EM); if (err != 0) printf_s("_controlfp_s failed!\n"); try { u[0] = func(); printf_s ("Fail"); return(1); } catch (...) { printf_s ("Pass"); return(0); } }
Pass 

See also

Pragma directives and the __pragma and _Pragma keywords
fenv_access pragma
fp_contract pragma

close