指定函数的浮点行为。
语法
#pragma float_control
#pragma float_control( precise,{on|off} [, push])
#pragma float_control( except,{on|off} [, push])
#pragma float_control({push|pop})
选项
precise、 on | off、、 push
指定是启用 (on) 还是禁用 (off) 精确浮点语义。 有关与 /fp:precise 编译器选项差异的信息,请参阅“注解”部分。 可选 push 令牌将 float_control 的当前设置推送到内部编译器堆栈。
except、 on | off、、 push
指定是启用 (on) 还是禁用 (off) 浮点异常语义。 可选 push 令牌将 float_control 的当前设置推送到内部编译器堆栈。
当 except 也设置为 on 时,只能将 precise 设置为 on。
push
将当前的 float_control 设置推送到内部编译器堆栈。
pop
从内部编译器堆栈的顶部移除 float_control 设置,使其成为新的 float_control 设置。
注解
float_control
pragma 的行为与 /fp 编译器选项不同。
float_control
pragma 只管理部分浮点行为。 必须将其与 fp_contract 和 fenv_accesspragma 指令组合在一起才能重新创建 /fp 编译器选项。 下表显示了每个编译器选项的等效 pragma 设置:
| 选项 | float_control(precise, *) |
float_control(except, *) |
fp_contract(*) |
fenv_access(*) |
|---|---|---|---|---|
/fp:strict |
on |
on |
off |
on |
/fp:precise |
on |
off |
off* |
off |
/fp:fast |
off |
off |
on |
off |
* 在 Visual Studio 2022 之前的 Visual Studio 版本中,/fp:precise 行为默认为 fp_contract(on)。
| 选项 | float_control(precise, *) |
float_control(except, *) |
fp_contract(*) |
fenv_access(*) |
|---|---|---|---|---|
/fp:strict |
on |
on |
off |
on |
/fp:precise |
on |
off |
off |
off |
/fp:fast |
off |
off |
on |
off |
换句话说,可能需要结合使用多个 pragma 指令来模拟 /fp:fast、/fp:precise 和 /fp:strict 命令行选项。
组合使用 float_control 和 fenv_access 浮点 pragma 指令的方式有一些限制:
仅当启用精确语义时,才能使用
float_control将except设置为on。 精确语义可以通过float_controlpragma 或使用/fp:precise或/fp:strict编译器选项来启用。启用异常语义(无论是通过
float_controlprecise还是float_control编译器选项)时,不能使用 pragma 来关闭/fp:except。除非通过
fenv_accessfloat_control或编译器选项启用了精确语义,否则无法启用 pragma。启用
float_control时,不能使用precise关闭fenv_access。
这些限制意味着一些浮点 pragma 指令的顺序非常重要。 若要使用 pragma 指令从快速模式转到严格模式,请使用以下代码:
#pragma float_control(precise, on) // enable precise semantics
#pragma fenv_access(on) // enable environment sensitivity
#pragma float_control(except, on) // enable exception semantics
#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
若要使用 float_controlpragma 从严格模式转到快速模式,请使用以下代码:
#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
如果未指定任何选项,则 float_control 不起作用。
当 float_control 指令打开 precise 或 except 时,它将禁用收缩。 使用 float_control 关闭 precise 或 except 将还原先前的收缩设置。 可以使用 fp_contractpragma 指令更改收缩时的编译器行为。
float_control(push) 和 float_control(pop) 将收缩设置作为 float_control 设置的一部分推送并弹出到内部编译器堆栈。 这是 Visual Studio 2022 中的新行为。 以前的编译器版本中的 float_control 指令不会影响收缩设置。
示例
以下示例演示如何通过使用 pragmafloat_control 捕获溢出浮点异常。
// pragma_directive_float_control.cpp
// compile with: /EHa
#include <stdio.h>
#include <float.h>
double func( ) {
return 1.1e75;
}
#pragma float_control (except, on)
int main( ) {
float u[1];
unsigned int currentControl;
errno_t err;
err = _controlfp_s(¤tControl, ~_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
另请参阅
Pragma 指令和 __pragma 和 _Pragma 关键字
fenv_access pragma
fp_contract pragma