__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