__assume
Sezione specifica Microsoft
Passa un hint all'utilità di ottimizzazione.
Sintassi
__assume(
expression
)
Parametri
expression
Per il codice raggiungibile, qualsiasi espressione che si presuppone restituisca true
. Usare 0
per indicare il codice non raggiungibile per l'utilità di ottimizzazione.
Osservazioni:
L'ottimizzatore presuppone che la condizione rappresentata da expression
sia true
nel punto in cui viene visualizzata la parola chiave e rimane true fino a quando expression
non viene modificata (ad esempio, assegnando a una variabile). L'uso selettivo degli hint passati all'utilità di ottimizzazione da __assume
possono migliorare l'ottimizzazione.
Se l'istruzione __assume
viene scritta come contraddizione (un'espressione che restituisce false
sempre ), viene sempre considerata come __assume(0)
. Se il codice non si comporta come previsto, assicurarsi che l'oggetto expression
definito sia valido e true
, come descritto in precedenza. L'istruzione __assume(0)
è un caso speciale. Usare __assume(0)
per indicare un percorso di codice che non può essere raggiunto.
Avviso
Un programma non deve contenere un'istruzione __assume
non valida in un percorso raggiungibile. Se il compilatore può raggiungere un'istruzione __assume
non valida, il programma potrebbe causare un comportamento imprevedibile e potenzialmente pericoloso.
Per la compatibilità con le versioni precedenti, _assume
è un sinonimo di __assume
a meno che non sia specificata l'opzione /Za
del compilatore (Disabilita estensioni del linguaggio).
__assume
non è un vero intrinseco. Non deve essere dichiarata come funzione e non può essere usata in una #pragma intrinsic
direttiva. Anche se non viene generato alcun codice, viene interessato il codice generato dall'utilità di ottimizzazione.
Usare __assume
in un oggetto ASSERT
solo quando l'asserzione non è recuperabile. Non usare __assume
in un'asserzione per cui si dispone di codice di ripristino degli errori successivo perché il compilatore potrebbe ottimizzare il codice di gestione degli errori.
Requisiti
Intrinsic | Architettura |
---|---|
__assume |
x86, ARM, x64, ARM64, ARM64EC |
Esempio
L'esempio seguente illustra come usare __assume(0)
per indicare che non è possibile raggiungere il default
caso di un'istruzione switch
. È l'uso più tipico di __assume(0)
. In questo caso, il programmatore sa che gli unici input possibili per p
saranno 1 o 2. Se viene passato un altro valore per p
, il programma diventa non valido e causa un comportamento imprevedibile.
// 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.
}
}
In seguito all'istruzione __assume(0)
, il compilatore non genera codice per verificare se p
ha un valore non rappresentato in un'istruzione case.
Se non si è certi che l'espressione sia true
sempre in fase di esecuzione, è possibile usare la assert
funzione per proteggere il codice. Questa definizione di macro esegue il wrapping dell'istruzione __assume
con un controllo:
#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))
Per il funzionamento dell'ottimizzazione default
del case, l'istruzione __assume(0)
deve essere la prima istruzione nel corpo del default
case. Sfortunatamente, nella assert
macro impedisce al ASSUME
compilatore di eseguire questa ottimizzazione. In alternativa, è possibile usare una macro separata, come illustrato di seguito:
#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT assert(0)
#else
# define NODEFAULT __assume(0)
#endif
// . . .
default:
NODEFAULT;
Fine sezione specifica Microsoft