__assume

Microsoft 专用

传递优化程序提示。

语法

__assume(
   expression
)

参数

expression
对于可访问代码,假设评估为 true 的任何表达式。 使用 0 向优化程序指示无法访问的代码。

备注

优化程序假设在关键字出现的地方由 expression 表示的条件为 true 并且直到修改 expression(例如,通过给变量赋值)前一直为 true。 选择性使用通过 __assume 传递给优化程序的提示可以完善优化。

如果将 __assume 语句写成矛盾(始终评估为 false 的表达式),则其始终会被视为 __assume(0)。 如果代码表现得不如预期,确保你定义的 expression 为有效和 true,如前所述。 __assume(0) 语句是一个特例。 使用 __assume(0) 来表示无法到达的代码路径。

警告

程序的可达路径不得包含无效的 __assume 语句。 如果编译器可以到达无效的 __assume 语句,程序可能会导致不可预测的潜在危险行为。

为了与以前的版本兼容,除非指定了编译器选项 /Za(禁用语言扩展),否则 _assume__assume 的同义词。

__assume 不是真正的内部函数。 不必将其声明为函数,也不能在 #pragma intrinsic 指令中使用它。 尽管没有生成任何代码,但还是会对由优化程序生成的代码产生影响。

只有在断言不可恢复时,才能在 ASSERT 中使用 __assume。 请勿在其中有后续错误恢复代码的断言中使用 __assume,因为编译器可能优化掉错误处理的代码。

要求

Intrinsic 体系结构
__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 专用

另请参阅

编译器内部函数
关键字