float_control pragma

Especifica el comportamiento de punto flotante de una función.

Sintaxis

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

Opciones

precise, on | off, push
Especifica si se va a habilitar (on) o deshabilitar (off) la semántica precisa de punto flotante. Para obtener información sobre las diferencias con la opción /fp:precise del compilador, consulte la sección Comentarios. El token opcional push inserta la configuración actual de float_control en la pila interna del compilador.

except, on | off, push
Especifica si se va a habilitar (on) o deshabilitar (off) la semántica de excepciones de punto flotante. El token opcional push inserta la configuración actual de float_control en la pila interna del compilador.

except solo se puede establecer en on si precise también se establece en on.

push
Inserta el valor de float_control actual en la pila interna del compilador.

pop
Elimina el valor de float_control de la parte superior de la pila interna del compilador y lo convierte en el nuevo valor de float_control.

Comentarios

float_controlpragma no tiene el mismo comportamiento que la opción /fp del compilador. float_controlpragma solo gobierna parte del comportamiento de punto flotante. Debe combinarse con directivas fp_contract y fenv_accesspragma para volver a crear las opciones /fp del compilador. En la tabla siguiente se muestra el valor equivalente pragma para cada opción del compilador:

Opción 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

* En versiones de Visual Studio anteriores a Visual Studio 2022, el comportamiento predeterminado de /fp:precise es fp_contract(on).

Opción 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

En otras palabras, es posible que tenga que usar varias directivas pragma combinadas para emular las opciones de línea de comandos /fp:fast, /fp:precise y /fp:strict.

Hay restricciones en las formas en que puede usar las directivas float_control y fenv_access de punto flotante pragma combinadas:

  • Solo puede usar float_control para establecer except en on si la semántica precisa está habilitada. La semántica precisa se puede habilitar mediante float_controlpragma o mediante las opciones del compilador /fp:precise o /fp:strict.

  • No se puede usar float_control para desactivar precise si la semántica de excepciones está habilitada, ya sea mediante float_controlpragma o una opción /fp:except del compilador.

  • No se puede habilitar fenv_access a menos que la semántica precisa esté habilitada, ya sea mediante float_controlpragma o una opción del compilador.

  • No se puede usar float_control para desactivar precise cuando fenv_access está habilitado.

Estas restricciones significan que el orden de algunas directivas pragma de punto flotante es significativo. Para pasar de un modelo rápido a un modelo estricto con directivas pragma, utilice el código siguiente:

#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

Para pasar de un modelo estricto a un modelo rápido mediante float_controlpragma, utilice el código siguiente:

#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

Si no se especifica ninguna opción, float_control no tiene ningún efecto.

La directiva float_control deshabilita las contracciones cuando activa precise o except. El uso de float_control para desactivar precise o except restaura la configuración anterior para contracciones. Puede usar la directiva fp_contractpragma para cambiar el comportamiento del compilador en las contracciones. float_control(push) y float_control(pop) insertan y sacan la configuración de las contracciones como parte del valor float_control en la pila interna del compilador. Este comportamiento es nuevo en Visual Studio 2022. La directiva float_control de las versiones anteriores del compilador no afectaba a la configuración de las contracciones.

Ejemplo

En el ejemplo siguiente se muestra cómo detectar una excepción de desbordamiento de punto flotante mediante 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(&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

Consulte también

Directivas pragma y las palabras clave __pragma y _Pragma
fenv_access pragma
fp_contract pragma