Compartilhar via


__assume

Seção específica da Microsoft

Passa uma dica para o otimizador.

Sintaxe

__assume(
   expression
)

Parâmetros

expression
Para código acessível, qualquer expressão supostamente avaliada como true. Use 0 para indicar um código inacessível para o otimizador.

Comentários

O otimizador presume que a condição representada por expression é trueno ponto em que a palavra-chave aparece e permanece verdadeira até que a expression seja modificada (por exemplo, atribuindo a uma variável). O uso seletivo de dicas passadas para o otimizador por __assume pode melhorar a otimização.

Se a instrução __assume for gravada como uma contradição (uma expressão que sempre avalia como false), ela sempre será tratada como __assume(0). Se o seu código não está funcionando como esperado, verifique se a expression que você definiu é válida e true, conforme descrito anteriormente. A instrução __assume(0) é um caso especial. Use __assume(0) para indicar um caminho de código que não pode ser alcançado.

Aviso

Um programa não deve conter uma instrução __assume inválida em um caminho acessível. Se o compilador puder acessar uma instrução __assume inválida, o programa pode causar comportamento imprevisível e potencialmente perigoso.

Para compatibilidade com versões anteriores, _assume é um sinônimo para __assume, a menos que a opção do compilador /Za (Desabilitar extensões de linguagem) seja especificada.

__assume não é um intrínseco verdadeiro. Ele não precisa ser declarado como uma função e não pode ser usado em uma diretiva #pragma intrinsic. Embora nenhum código seja gerado, o código gerado pelo otimizador é afetado.

Use __assume em um ASSERT somente quando a declaração não for recuperável. Não use __assume em uma declaração para a qual você tem código de recuperação de erro subsequente porque o compilador pode otimizar o código de tratamento do erro.

Requisitos

Intrinsic Arquitetura
__assume x86, ARM, x64, ARM64, ARM64EC

Exemplo

O exemplo a seguir mostra como usar __assume(0) para indicar que o caso default de uma instrução switch não pode ser alcançado. É o uso mais comum de __assume(0). Aqui, o programador sabe que as entradas possíveis para p será 1 ou 2. Se outro valor for passado p, o programa se tornará inválido e causará um comportamento imprevisível.

// compiler_intrinsics__assume.cpp

void func1(int /*ignored*/)
{
}

int main(int p)
{
   switch(p)
   {
   case 1:
      func1(1);
      break;
   case 2:
      func1(-1);
      break;
   default:
      __assume(0);
      // This tells the optimizer that the default
      // cannot be reached. As so, it does not have to generate
      // the extra code to check that 'p' has a value
      // not represented by a case arm. This makes the switch
      // run faster.
   }
}

Como resultado da instrução __assume(0), o compilador não gera código para testar se p possui um valor que não é representado em uma instrução de caso.

Se você não tiver certeza de que a expressão sempre será true em tempo de execução, pode usar a função assert para proteger o código. Essa definição de macro encapsula a instrução __assume com uma verificação:

#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))

Para que a otimização do caso default funcione, a instrução __assume(0) deve ser a primeira no corpo do caso default. Infelizmente, a assert na macro ASSUME impede que o compilador execute essa otimização. Como alternativa, você pode usar uma macro separada, conforme mostrado a seguir:

#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT   assert(0)
#else
# define NODEFAULT   __assume(0)
#endif
// . . .
   default:
      NODEFAULT;

Fim da seção específica da Microsoft

Confira também

Intrínsecos do compilador
Palavras-chave