Compartir a través de


__assume

Específicos de Microsoft

Pasa una sugerencia al optimizador.

Sintaxis

__assume(
   expression
)

Parámetros

expression
Para el código accesible, cualquier expresión que se supone que se evalúa como true. Use 0 para indicar código inaccesible al optimizador.

Comentarios

El optimizador supone que la condición representada por expression es true en el punto donde aparece la palabra clave y sigue siendo verdadera hasta que se modifica expression (por ejemplo, mediante la asignación a una variable). El uso selectivo de las sugerencias que __assume pasa al optimizador puede mejorar la optimización.

Si la instrucción __assume se escribe como una contradicción (es decir, una expresión que siempre se evalúa como false), siempre se trata como __assume(0). Si el código no se comporta de la forma esperada, asegúrese de que la instancia de expression que ha definido es válida y true, como se ha descrito antes. La instrucción __assume(0) es un caso especial. Use __assume(0) para indicar una ruta de acceso al código que no es accesible.

Advertencia

Un programa no debe contener una instrucción __assume no válida en una ruta accesible. Si el compilador puede acceder a una instrucción __assume no válida, el programa podría ocasionar un comportamiento impredecible y potencialmente peligroso.

A efectos de compatibilidad con versiones anteriores, _assume es un sinónimo de __assume a menos que se especifique la opción del compilador /Za (Deshabilitar extensiones de lenguaje).

__assume no es un intrínseco auténtico. No se tiene que declarar como una función y no se puede usar en una directiva #pragma intrinsic. Aunque no se genera ningún código, el código generado por el optimizador se ve afectado.

Use __assume en ASSERT solo cuando la aserción no se pueda recuperar. No use __assume en una aserción para la que tenga código de recuperación de errores posterior, ya que el compilador podría optimizar el código de control de errores.

Requisitos

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

Ejemplo

En el ejemplo siguiente se muestra cómo usar __assume(0) para indicar que no se puede alcanzar el caso default de una instrucción switch. Es el uso más típico de __assume(0). Aquí, el programador sabe que las únicas entradas posibles para p son 1 o 2. Si se pasa otro valor para p, el programa deja de ser válido y provoca un comportamiento impredecible.

// 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 de la instrucción __assume(0), el compilador no genera código para comprobar si p tiene un valor que no está representado en una instrucción case.

Si no está seguro de que la expresión siempre será true en tiempo de ejecución, puede usar la función assert para proteger el código. Esta definición de macro encapsula la instrucción __assume con una comprobación:

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

Para que la optimización del caso default funcione, la instrucción __assume(0) debe ser la primera en el cuerpo del caso default. Desafortunadamente, la instancia assert de la macro ASSUME impide que el compilador realice esta optimización. Como alternativa, puede usar una macro independiente, como se muestra aquí:

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

FIN de Específicos de Microsoft

Consulte también

Intrínsecos del compilador
Palabras clave