fenv_access pragma

禁用 (on) 或启用 (off) 可能更改浮点环境标志测试和模式更改的优化。

语法

#pragma fenv_access ( { on | off } )

注解

默认情况下,fenv_accessoff。 编译器假定代码无法访问或操作浮点环境。 如果不需要环境访问,编译器可以执行更多操作来优化浮点代码。

如果代码测试浮点状态标志、异常或设置控制模式标志,请启用 fenv_access。 编译器禁用浮点优化,因此代码始终可以访问浮点环境。

/fp:strict 命令行选项自动启用 fenv_access。 有关此浮点行为和其他浮点行为的详细信息,请参阅 /fp(指定浮点数行为)

fenv_accesspragma 与其他浮点设置结合使用的方式存在限制:

  • 除非启用了精确的语义,否则无法启用 fenv_access。 精确语义可以通过 float_controlpragma 或使用 /fp:precise/fp:strict 编译器选项来启用。 如果未指定其他浮点命令行选项,则编译器默认为 /fp:precise

  • 设置 fenv_access(on) 时,不能使用 float_control 禁用精确语义。

fenv_access(on) 指令禁止生成浮点收缩,即结合浮点运算的机器指令fenv_access(off) 还原以前的收缩行为。 这是 Visual Studio 2022 中的新行为。 默认情况下,以前的编译器版本可以在 fenv_access(on) 下生成收缩。 有关浮点收缩的详细信息,请参阅 /fp:contract

具有 fenv_access 约束的优化类型如下:

  • 全局公共子表达式消除

  • 代码运动

  • 常量折叠

其他浮点 pragma 指令包括:

示例

本示例将 fenv_access 设置为 on 以设置 24 位精度的浮点控制寄存器:

// pragma_directive_fenv_access_x86.cpp
// compile with: /O2 /arch:IA32
// processor: x86
#include <stdio.h>
#include <float.h>
#include <errno.h>
#pragma fenv_access (on)

int main() {
   double z, b = 0.1, t = 0.1;
   unsigned int currentControl;
   errno_t err;

   err = _controlfp_s(&currentControl, _PC_24, _MCW_PC);
   if (err != 0) {
      printf_s("The function _controlfp_s failed!\n");
      return -1;
   }
   z = b * t;
   printf_s ("out=%.15e\n",z);
}
out=9.999999776482582e-03

如果从上一个示例注释禁止 #pragma fenv_access (on) ,则输出不同。 这是因为编译器会进行编译时评估,而编译时评估不会使用控制模式。

// pragma_directive_fenv_access_2.cpp
// compile with: /O2 /arch:IA32
#include <stdio.h>
#include <float.h>

int main() {
   double z, b = 0.1, t = 0.1;
   unsigned int currentControl;
   errno_t err;

   err = _controlfp_s(&currentControl, _PC_24, _MCW_PC);
   if (err != 0) {
      printf_s("The function _controlfp_s failed!\n");
      return -1;
   }
   z = b * t;
   printf_s ("out=%.15e\n",z);
}
out=1.000000000000000e-02

另请参阅

Pragma 指令以及 __pragma_Pragma 关键字