Partilhar via


__assume

Específico da Microsoft

Passa uma dica para o otimizador.

__assume(    expression )

Parâmetros

  • expression
    Qualquer expressão supostamente avaliada como verdadeira.

Comentários

O otimizador presume que a condição representada por expression é verdadeira no 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 falso), ela sempre será tratada como __assume(0). Se seu código não está funcionando como esperado, verifique se a expression que você definiu é válida e verdadeira, conforme descrito anteriormente. Para obter mais informações sobre comportamento esperado de __assume(0), consulte os comentários posteriores.

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.

__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 só quando o assert não for recuperável. Não use __assume em um assert para o qual você tem código de recuperação de erro subsequente porque o compilador pode otimizar o código de tratamento do erro.

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. O exemplo a seguir mostra como usar __assume(0) para indicar que o caso de padrão de uma instrução switch não pode ser alcançado. Isso mostra o uso mais comum de __assume(0).

Requisitos

Intrínseco

Arquitetura

__assume

x86, ARM, x64

Exemplo

// compiler_intrinsics__assume.cpp
#ifdef DEBUG
# define ASSERT(e)    ( ((e) || assert(__FILE__, __LINE__) )
#else
# define ASSERT(e)    ( __assume(e) )
#endif

void func1(int i)
{
}

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.
   }
}

O uso de __assume(0) informa ao otimizador que o caso padrão não pode ser acessado. O exemplo demonstra que 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.

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. Para que isso funcione, a instrução __assume(0) deve ser a primeira no corpo do caso padrão.

Como o compilador gera código com base em __assume, esse código pode não ser executado corretamente se expressão dentro da instrução __assume for falsa em tempo de execução. Se você não tiver certeza de que a expressão sempre será verdadeira em tempo de execução, pode usar a função assert para proteger o código.

#define ASSERT(e)    ( ((e) || assert(__FILE__, __LINE__)), __assume(e) )

Infelizmente, esse uso de assert impede que o compilador execute a otimização de caso padrão descrita anteriormente neste documento. Como alternativa, você pode usar uma macro separada, como a seguir.

#ifdef DEBUG
# define NODEFAULT   ASSERT(0)
#else
# define NODEFAULT   __assume(0)
#endif

   default:
      NODEFAULT;

Consulte também

Referência

Intrínsecos do compilador

Palavras-chave C++