__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 专用