__assume
Microsoft Specific
Passes a hint to the optimizer.
Syntax
__assume(
expression
)
Parameters
expression
For reachable code, any expression that is assumed to evaluate to true
. Use 0
to indicate unreachable code to the optimizer.
Remarks
The optimizer assumes that the condition represented by expression
is true
at the point where the keyword appears and remains true until expression
is modified (for example, by assignment to a variable). Selective use of hints passed to the optimizer by __assume
can improve optimization.
If the __assume
statement is written as a contradiction (an expression that always evaluates to false
), it's always treated as __assume(0)
. If your code isn't behaving as expected, ensure that the expression
you defined is valid and true
, as described earlier. The __assume(0)
statement is a special case. Use __assume(0)
to indicate a code path that can't be reached.
Warning
A program must not contain an invalid __assume
statement on a reachable path. If the compiler can reach an invalid __assume
statement, the program might cause unpredictable and potentially dangerous behavior.
For compatibility with previous versions, _assume
is a synonym for __assume
unless compiler option /Za
(Disable language extensions) is specified.
__assume
isn't a genuine intrinsic. It doesn't have to be declared as a function and it can't be used in a #pragma intrinsic
directive. Although no code is generated, the code generated by the optimizer is affected.
Use __assume
in an ASSERT
only when the assertion isn't recoverable. Don't use __assume
in an assertion for which you have subsequent error recovery code because the compiler might optimize away the error-handling code.
Requirements
Intrinsic | Architecture |
---|---|
__assume |
x86, ARM, x64, ARM64, ARM64EC |
Example
The following example shows how to use __assume(0)
to indicate that the default
case of a switch
statement can't be reached. It's the most typical use of __assume(0)
. Here, the programmer knows that the only possible inputs for p
will be 1 or 2. If another value is passed in for p
, the program becomes invalid and causes unpredictable behavior.
// 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.
}
}
As a result of the __assume(0)
statement, the compiler doesn't generate code to test whether p
has a value that isn't represented in a case statement.
If you aren't sure that the expression will always be true
at runtime, you can use the assert
function to protect the code. This macro definition wraps the __assume
statement with a check:
#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))
For the default
case optimization to work, the __assume(0)
statement must be the first statement in the body of the default
case. Unfortunately, the assert
in the ASSUME
macro prevents the compiler from performing this optimization. As an alternative, you can use a separate macro, as shown here:
#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT assert(0)
#else
# define NODEFAULT __assume(0)
#endif
// . . .
default:
NODEFAULT;
END Microsoft Specific