__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
é true
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 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