命名空间
变体
操作

C++ 属性:assume (C++23 起)

来自 cppreference.cn
< cpp‎ | 语言‎ | 属性
 
 
C++ 语言
 
 
属性
assume
(C++23)
(C++11)(直至 C++26)
(C++14)
(C++20)
(C++17)
(C++11)
(C++20)
 

指定假定给定的表达式在给定点始终评估为 true,以允许编译器根据给定的信息进行优化。

目录

[编辑] 语法

[[assume( 表达式 )]]
表达式 - 任何表达式(除了未加括号的逗号表达式

[编辑] 解释

[[assume]] 只能应用于空语句,如 [[assume(x > 0)]];。此语句称为假定

表达式上下文转换为bool,但它不被求值(它仍然是潜在求值)。

  • 如果转换后的 表达式 在假定出现的位置求值为 true,则假定没有效果。
  • 否则,假定的求值具有运行时未定义行为

[编辑] 注意

由于假定如果不成立会导致运行时未定义行为,因此应谨慎使用。

一种正确的使用方法是在断言之后使用假定

assert(x > 0);     // trigger an assertion when NDEBUG is not defined and x > 0 is false
[[assume(x > 0)]]; // provide optimization opportunities when NDEBUG is defined

[编辑] 示例

#include <cmath>
 
void f(int& x, int y)
{
    void g(int);
    void h();
 
    [[assume(x > 0)]]; // Compiler may assume x is positive
 
    g(x / 2); // More efficient code possibly generated
 
    x = 3;
    int z = x;
 
    [[assume((h(), x == z))]]; // Compiler may assume x would have the same value after
                               // calling h
                               // The assumption does not cause a call to h
 
    h();
    g(x); // Compiler may replace this with g(3);
 
    h();
    g(x); // Compiler may NOT replace this with g(3);
          // An assumption applies only at the point where it appears
 
    z = std::abs(y);
 
    [[assume((g(z), true))]]; // Compiler may assume g(z) will return
 
    g(z); // Due to above and below assumptions, compiler may replace this with g(10);
 
    [[assume(y == -10)]]; // Undefined behavior if y != -10 at this point
 
    [[assume((x - 1) * 3 == 12)]];
 
    g(x); // Compiler may replace this with g(5);
}

[编辑] 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 发布时的行为 正确的行为
CWG 2924 C++23 违反假定将导致未定义行为 导致运行时未定义行为

[编辑] 参考

  • C++23 标准 (ISO/IEC 14882:2024)
  • 9.12.3 假定属性 [dcl.attr.assume]

[编辑] 参见

标记不可达的执行点
(函数) [编辑]
contract_assert 语句 (C++26) 在执行期间验证内部条件[编辑]

[编辑] 外部链接

1.  Clang 语言扩展文档:__builtin_assume
2.  Clang 属性参考文档:assume
3.  MSVC 文档:__assume 内建函数。
4.  GCC 文档:__attribute__((assume(...)))