__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 固有の仕様はここまで