__assume__assume

Microsoft 固有の仕様Microsoft Specific

オプティマイザーにヒントを渡します。Passes a hint to the optimizer.

構文Syntax

__assume(
   expression
)

パラメーターParameters

式 (expression)expression
評価が true になると想定される式。Any expression that is assumed to evaluate to true.

RemarksRemarks

オプティマイザーでは、expression で表される条件は、このキーワードが指定された時点で true であり、expression が変更されるまで (変数への代入などにより) true のままであると想定します。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). __assume がオプティマイザーに渡すヒントを選択的に使用することで、より優れた最適化を行うことができます。Selective use of hints passed to the optimizer by __assume can improve optimization.

__assume ステートメントが否定 (常に false に評価される式) として記述された場合は、常に __assume(0) として処理されます。If the __assume statement is written as a contradiction (an expression that always evaluates to false), it is always treated as __assume(0). コードが期待どおりに動作しない場合は、前述のとおり、定義した expression が有効かつ true であることを確認してください。If your code isn’t behaving as expected, ensure that the expression you defined is valid and true, as described earlier. 想定される __assume(0) の動作の詳細については、以降の解説を参照してください。For more information about expected __assume(0) behavior, see the later remarks.

警告

プログラムの到達可能なパスには、無効な __assume ステートメントを含めないでください。A program must not contain an invalid __assume statement on a reachable path. コンパイラが無効な __assume ステートメントに到達することがあると、予測できない、悪影響のある動作がプログラムで発生するおそれがあります。If the compiler can reach an invalid __assume statement, the program might cause unpredictable and potentially dangerous behavior.

__assume は正規の組み込みではありません。__assume is not a genuine intrinsic. これは関数として宣言する必要がなく、また #pragma 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.

使用__assumeで、 ASSERTアサートがいない場合のみ回復可能な。Use __assume in an ASSERT only when the assert is not recoverable. コンパイラがエラー処理コードを最適化する場合があるため、後続のエラー回復コードを含むアサートに __assume を使用しないでください。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.

__assume(0) このステートメントは特殊なケースです。The __assume(0) statement is a special case. 到達できないコード パスを示すために __assume(0) を使用します。Use __assume(0) to indicate a code path that cannot be reached. 次の例では、switch ステートメントの default ケースに到達できないことを示すために __assume(0) を使用します。The following example shows how to use __assume(0) to indicate that the default case of a switch statement cannot be reached. これは、__assume(0) の最も一般的な使用方法です。This shows the most typical use of __assume(0).

以前のバージョンとの互換性のため _assumeのシノニムです _assumeしない限り、コンパイラ オプション/Za(言語拡張機能を無効にする)は指定します。For compatibility with previous versions, _assume is a synonym for __assume unless compiler option /Za (Disable language extensions) is specified.

必要条件Requirements

組み込みIntrinsic アーキテクチャArchitecture
__assume x86、ARM、x64x86, ARM, 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.
   }
}

__assume(0) を使用すると、default ケースに到達できないことがオプティマイザーに通知されます。The use of __assume(0) tells the optimizer that the default case cannot be reached. この例では、p には 1 または 2 しか入力されないことをプログラマが認識していることを示しています。The example demonstrates that the programmer knows that the only possible inputs for p will be 1 or 2. 別の値が p に渡された場合は、プログラムが無効になり予期しない動作が発生します。If another value is passed in for p, the program becomes invalid and causes unpredictable behavior.

__assume(0) ステートメントの結果、コンパイラは case ステートメントで代表されない値が p に入るかどうかをテストするコードを生成しません。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. このため、__assume(0) ステートメントは default ケースの本文の最初のステートメントとする必要があります。For this to work, the __assume(0) statement must be the first statement in the body of the default case.

コンパイラでは __assume を基にしてコードを生成するため、__assume ステートメント内の式が実行時に false となる場合、そのコードは正しく動作しない可能性があります。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. 実行時に式が常に true となることが確認できない場合は、assert 関数を使用するとコードを保護することができます。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) )

ただし、このように assert を使用すると、このドキュメントで既に説明した default ケースの最適化がコンパイラで実行されなくなります。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;

Microsoft 固有の仕様はここまでEND Microsoft Specific

関連項目See also

コンパイラの組み込みCompiler Intrinsics
キーワードKeywords