Partilhar via


float_control pragma

Especifica o comportamento de ponto flutuante para uma função.

Sintaxe

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

Opções

precise, on | off, push
Especifica se é necessário habilitar (on) ou desabilitar (off) a semântica precisa de ponto flutuante. Para obter informações sobre diferenças com a opção do compilador /fp:precise, consulte a seção Comentários. O token opcional push envia a configuração atual por push para float_control na pilha interna do compilador.

except, on | off, push
Especifica se é necessário habilitar (on) ou desabilitar (off) a semântica de exceção de ponto flutuante. O token opcional push envia a configuração atual por push para float_control na pilha interna do compilador.

except só pode ser definido como on quando precise também estiver definido como on.

push
Envia por push a configuração atual defloat_control para a pilha interna do compilador.

pop
Remove a configuração de float_control da parte superior da pilha interna do compilador e faz dela a nova configuração de float_control.

Comentários

O float_controlpragma não tem o mesmo comportamento da opção do compilador /fp. O float_controlpragma rege apenas parte do comportamento de ponto flutuante. Ele deve ser combinado com as diretivas fp_contract e fenv_accesspragma para recriar as opções do compilador /fp. A tabela a seguir mostra as configurações equivalentes de pragma para cada opção do compilador:

Opção 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

* Em versões do Visual Studio anteriores ao Visual Studio 2022, o comportamento /fp:precise adotava fp_contract(on) como padrão.

Opção 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

Em outras palavras, pode ser necessário usar várias diretivas pragma combinadas para emular as opções de linha de comando /fp:fast, /fp:precise e /fp:strict.

Há restrições nas maneiras como você pode usar as diretivas de ponto flutuante pragma float_control e fenv_access combinadas:

  • Você só poderá usar float_control para definir except como on se a semântica precisa estiver habilitada. A semântica precisa pode ser habilitada pelas opções float_controlpragma ou usando as opções de compilador /fp:precise ou /fp:strict.

  • Você não pode usar float_control para desativar precise quando a semântica de exceção estiver habilitada, seja por uma opção de float_controlpragma ou /fp:except.

  • Você não pode habilitar fenv_access a menos que a semântica precisa esteja habilitada, seja por float_controlpragma ou por uma opção do compilador.

  • Você não pode usar float_control para desativar precise quando fenv_access estiver habilitado.

Essas restrições significam que a ordem de algumas diretivas de ponto flutuante pragma é significativa. Para ir do modelo rápido para um modelo estrito com as diretivas pragma, use o seguinte código:

#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 ir do modelo estrito para um modelo rápido com as diretivas float_controlpragma, use o seguinte código:

#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

Se nenhuma opção for especificada, float_control não terá efeito.

A diretiva float_control desabilita contrações quando ativa precise ou except. O uso de float_control para desativar precise ou except restaura a configuração anterior para contrações. Você pode usar a diretiva fp_contractpragma para alterar o comportamento do compilador em contrações. float_control(push) e float_control(pop) efetuam push e colocam a configuração para contrações como parte da configuração float_control na pilha do compilador interno. Esse comportamento é novo no Visual Studio 2022. A diretiva float_control em versões anteriores do compilador não afetou as configurações de contração.

Exemplo

O exemplo a seguir mostra como capturar uma exceção de ponto flutuante de estouro usando 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

Confira também

Pragmadiretivas e as __pragma palavras-chave e _Pragma
fenv_access pragma
fp_contract pragma