Поделиться через


__assume

Microsoft Specific

Passes a hint to the optimizer.

__assume(
   expression
)

Parameters

  • expression
    Any expression that is assumed to evaluate to true.

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 is 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. For more information about expected __assume(0) behavior, see the later remarks.

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.

__assume is not a genuine intrinsic. It does not have to be declared as a function and it cannot 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 assert is not recoverable. Do not use __assume in an assert for which you have subsequent error recovery code because the compiler might optimize away the error-handling code.

The __assume(0) statement is a special case. Use __assume(0) to indicate a code path that cannot be reached. The following example shows how to use __assume(0) to indicate that the default case of a switch statement cannot be reached. This shows the most typical use of __assume(0).

Requirements

Intrinsic

Architecture

__assume

x86, IPF, x64

Example

// compiler_intrinsics__assume.cpp
#ifdef DEBUG
# define ASSERT(e)    ( ((e) || assert(__FILE__, __LINE__) )
#else
# define ASSERT(e)    ( __assume(e) )
#endif

void func1(int i)
{
}

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.
   }
}

The use of __assume(0) tells the optimizer that the default case cannot be reached. The example demonstrates that 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.

As a result of the __assume(0) statement, the compiler does not generate code to test whether p has a value that is not represented in a case statement. For this to work, the __assume(0) statement must be the first statement in the body of the default case.

Because the compiler generates code based on __assume, that code might not run correctly if the expression inside the __assume statement is false at run time. If you are not sure that the expression will always be true at run time, you can use the assert function to protect the code.

# define ASSERT(e)    ( ((e) || assert(__FILE__, __LINE__)), __assume(e) )

Unfortunately, this use of assert prevents the compiler from performing the default-case optimization that was described earlier in this document. As an alternative, you can use a separate macro, as follows.

#ifdef DEBUG
# define NODEFAULT   ASSERT(0)
#else
# define NODEFAULT   __assume(0)
#endif

   default:
      NODEFAULT;

See Also

Reference

Compiler Intrinsics

C++ Keywords

Change History

Date

History

Reason

March 2011

Clarified the usage of assume(0).

Information enhancement.

October 2011

Added information about contradictory use of __assume

Customer feedback.