float_control
pragma
指定函数的浮点行为。
语法
#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
的当前设置推送到内部编译器堆栈。
当 precise
也设置为 on
时,只能将 except
设置为 on
。
push
将当前的 float_control
设置推送到内部编译器堆栈。
pop
从内部编译器堆栈的顶部移除 float_control
设置,使其成为新的 float_control
设置。
注解
float_control
pragma 的行为与 /fp
编译器选项不同。 float_control
pragma 只管理部分浮点行为。 必须将其与 fp_contract
和 fenv_access
pragma 指令组合在一起才能重新创建 /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_control
pragma 或使用/fp:precise
或/fp:strict
编译器选项来启用。启用异常语义(无论是通过
float_control
pragma 还是/fp:except
编译器选项)时,不能使用float_control
来关闭precise
。除非通过
float_control
pragma 或编译器选项启用了精确语义,否则无法启用fenv_access
。启用
fenv_access
时,不能使用float_control
关闭precise
。
这些限制意味着一些浮点 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_control
pragma 从严格模式转到快速模式,请使用以下代码:
#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_contract
pragma 指令更改收缩时的编译器行为。 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