__assume
Microsoft-spezifisch
Übergibt einen Hinweis an den Optimierer.
Syntax
__assume(
expression
)
Parameter
expression
Für erreichbaren Code wird von jedem Ausdruck ausgegangen, der true
ausgewertet wird. Wird verwendet 0
, um nicht erreichbaren Code für den Optimierer anzugeben.
Hinweise
Der Optimierer geht davon aus, dass sich die dargestellte expression
true
Bedingung an dem Punkt befindet, an dem das Schlüsselwort angezeigt wird und bis zur Änderung wahr expression
bleibt (z. B. durch Zuweisung zu einer Variablen). Durch die selektive Verwendung von Hinweisen, die von __assume
an den Optimierer übergeben werden, kann die Optimierung verbessert werden.
Wenn die __assume
Aussage als Widerspruch geschrieben wird (ein Ausdruck, der immer ausgewertet false
wird), wird sie immer als __assume(0)
behandelt. Wenn Ihr Code nicht wie erwartet angezeigt wird, stellen Sie sicher, dass die expression
von Ihnen definierten Werte gültig sind und true
, wie zuvor beschrieben. Die __assume(0)
-Anweisung ist ein Sonderfall. Wird __assume(0)
verwendet, um einen Codepfad anzugeben, der nicht erreicht werden kann.
Warnung
Ein Programm darf keine ungültige __assume
-Anweisung an einem erreichbaren Pfad enthalten. Wenn der Compiler eine ungültige __assume
-Anweisung erreichen kann, kann das Programm möglicherweise ein unvorhersehbares und möglicherweise gefährliches Verhalten verursachen.
Aus Gründen der Kompatibilität mit früheren Versionen ist _assume
ein Synonym für __assume
, es sei denn, die Compileroption /Za
(Spracherweiterungen deaktivieren) ist angegeben.
__assume
ist keine echte systeminterne. Sie muss nicht als Funktion deklariert werden und kann nicht in einer #pragma intrinsic
Direktive verwendet werden. Es wird zwar kein Code generiert, der vom Optimierer generierte Code ist jedoch davon betroffen.
Wird nur verwendet __assume
ASSERT
, wenn die Assertion nicht wiederhergestellt werden kann. Verwenden __assume
Sie nicht in einer Assertion, für die Sie nachfolgende Fehler Wiederherstellungscode haben, da der Compiler den Fehlerbehandlungscode möglicherweise entfernt.
Anforderungen
Intrinsic | Aufbau |
---|---|
__assume |
x86, ARM, x64, ARM64, ARM64EC |
Beispiel
Das folgende Beispiel zeigt, wie Sie angeben, __assume(0)
dass der default
Fall einer switch
Anweisung nicht erreicht werden kann. Es ist die typischste Verwendung von __assume(0)
. Hier weiß der Programmierer, dass die einzigen möglichen Eingaben für p
1 oder 2 sein werden. Wenn ein anderer Wert für p
übergeben wird, wird das Programm ungültig und führt zu unvorhersehbarem Verhalten.
// 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.
}
}
Als Ergebnis der __assume(0)
Anweisung generiert der Compiler keinen Code, um zu testen, ob p
ein Wert vorhanden ist, der nicht in einer Case-Anweisung dargestellt wird.
Wenn Sie nicht sicher sind, dass der Ausdruck immer zur Laufzeit ist true
, können Sie die assert
Funktion verwenden, um den Code zu schützen. Diese Makrodefinition umschließt die __assume
Anweisung mit einer Überprüfung:
#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))
Damit die default
Falloptimierung funktioniert, muss die __assume(0)
Anweisung die erste Anweisung im Textkörper des default
Falls sein. Leider verhindert das assert
Makro ASSUME
, dass der Compiler diese Optimierung ausführt. Alternativ können Sie ein separates Makro verwenden, wie hier gezeigt:
#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT assert(0)
#else
# define NODEFAULT __assume(0)
#endif
// . . .
default:
NODEFAULT;
Ende Microsoft-spezifisch