__assume
Section spécifique à Microsoft
Passe une indication à l'optimiseur.
Syntaxe
__assume(
expression
)
Paramètres
expression
Pour le code accessible, toute expression supposée évaluer .true
Permet 0
d’indiquer du code inaccessible à l’optimiseur.
Notes
L’optimiseur suppose que la condition représentée par expression
est true
au point où le mot clé apparaît et reste true jusqu’à ce qu’il expression
soit modifié (par exemple, par affectation à une variable). Une utilisation sélective des indications passées à l'optimiseur par __assume
peut améliorer l'optimisation.
Si l’instruction __assume
est écrite en tant que contradiction (expression qui prend toujours la false
valeur ), elle est toujours traitée comme __assume(0)
. Si votre code ne se comporte pas comme prévu, vérifiez que le code expression
que vous avez défini est valide et true
, comme décrit précédemment. L'instruction __assume(0)
est un cas spécial. Permet __assume(0)
d’indiquer un chemin de code qui ne peut pas être atteint.
Avertissement
Un programme ne doit pas contenir d'instruction __assume
non valide sur un chemin d'accès accessible. Si le compilateur peut atteindre une instruction __assume
non valide, le programme peut provoquer un comportement imprévisible et potentiellement dangereux.
Pour la compatibilité avec les versions précédentes, _assume
est un synonyme de __assume
, sauf si l’option du compilateur /Za
(Désactiver les extensions de langage) est spécifiée.
__assume
n’est pas une véritable intrinsèque. Il n’est pas obligé d’être déclaré en tant que fonction et il ne peut pas être utilisé dans une #pragma intrinsic
directive. Bien qu'aucun code ne soit généré, le code généré par l'optimiseur est affecté.
Utilisez-la __assume
uniquement ASSERT
lorsque l’assertion n’est pas récupérable. N’utilisez __assume
pas dans une assertion pour laquelle vous avez des code de récupération d’erreur ultérieures, car le compilateur peut optimiser le code de gestion des erreurs.
Spécifications
Intrinsic | Architecture |
---|---|
__assume |
x86, ARM, x64, ARM64, ARM64EC |
Exemple
L’exemple suivant montre comment utiliser __assume(0)
pour indiquer que la default
casse d’une switch
instruction ne peut pas être atteinte. C’est l’utilisation la plus classique de __assume(0)
. Ici, le programmeur sait que les seules entrées possibles pour p
seront 1 ou 2. Si une autre valeur est passée pour p
, le programme n'est plus valide et provoque un comportement imprévisible.
// 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.
}
}
À la suite de l’instruction __assume(0)
, le compilateur ne génère pas de code pour tester si p
une valeur n’est pas représentée dans une instruction case.
Si vous ne savez pas que l’expression sera toujours true
au moment de l’exécution, vous pouvez utiliser la assert
fonction pour protéger le code. Cette définition de macro encapsule l’instruction __assume
avec une vérification :
#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))
Pour que l’optimisation de default
la casse fonctionne, l’instruction __assume(0)
doit être la première instruction dans le corps du default
cas. Malheureusement, la assert
ASSUME
macro empêche le compilateur d’effectuer cette optimisation. En guise d’alternative, vous pouvez utiliser une macro distincte, comme illustré ici :
#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 la section spécifique à Microsoft