次の方法で共有


__assume

Microsoft 固有の仕様

オプティマイザーにヒントを渡します。

構文

__assume(
   expression
)

パラメーター

expression
到達可能なコードの場合、 trueに評価されると見なされるすべての式。 0を使用して、オプティマイザーに到達できないコードを示します。

解説

オプティマイザーは、 expression によって表される条件がキーワードが表示される時点で true され、 expression が変更されるまで true のままであると見なします (変数への代入など)。 __assume がオプティマイザーに渡すヒントを選択的に使用することで、より優れた最適化を行うことができます。

__assumeステートメントが矛盾として記述されている場合 (常にfalse評価される式)、常に__assume(0)として扱われます。 コードが期待どおりに動作しない場合は、前に説明したように、定義した expression が有効で trueされていることを確認します。 __assume(0) このステートメントは特殊なケースです。 __assume(0)を使用して、到達できないコード パスを示します。

警告

プログラムの到達可能なパスには、無効な __assume ステートメントを含めないでください。 コンパイラが無効な __assume ステートメントに到達することがあると、予測できない、悪影響のある動作がプログラムで発生するおそれがあります。

以前のバージョンとの互換性を確保するために、_assume は、コンパイラ オプション /Za (言語拡張機能の無効化) が指定されていない限り、__assume の同意語です。

__assume は本物の組み込みではありません。 関数として宣言する必要はありません。また、 #pragma intrinsic ディレクティブでは使用できません。 コードは生成されませんが、オプティマイザーが生成するコードには影響を与えます。

アサーションを回復できない場合にのみ、ASSERT__assumeを使用します。 コンパイラがエラー処理コードを最適化する可能性があるため、後続のエラーリカバリー コードがあるアサーションでは、__assumeを使用しないでください。

要件

Intrinsic Architecture
__assume x86、ARM、x64、ARM64、ARM64EC

次の例では、__assume(0)を使用して、switch ステートメントのdefaultケースに到達できないことを示します。 これは、 __assume(0)の最も一般的な用途です。 ここでは、プログラマは、 p に対して可能な唯一の入力が 1 または 2 であることを認識しています。 別の値が p に渡された場合は、プログラムが無効になり予期しない動作が発生します。

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

__assume(0) ステートメントの結果として、コンパイラは、pが case ステートメントで表されていない値を持っているかどうかをテストするコードを生成しません。

実行時に式が常に true されるかわからない場合は、 assert 関数を使用してコードを保護できます。 このマクロ定義は、 __assume ステートメントをチェックでラップします。

#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))

defaultケースの最適化を機能させるには、__assume(0) ステートメントがdefaultケースの本文の最初のステートメントである必要があります。 残念ながら、ASSUME マクロのassertにより、コンパイラがこの最適化を実行できなくなります。 別の方法として、次に示すように、別のマクロを使用できます。

#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT   assert(0)
#else
# define NODEFAULT   __assume(0)
#endif
// . . .
   default:
      NODEFAULT;

Microsoft 固有の仕様はここまで

関連項目

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