Namespaces
Variants

C++ attribute: assume (since C++23)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

指定在给定点假定表达式始终求值为 true ,以便编译器能基于所提供信息进行优化。

目录

语法

[ [ assume ( 表达式 ) ] ]
expression - 任意表达式(除未加括号的 逗号表达式 外)

说明

[ [ assume ] ] 仅能应用于 空语句 ,如 [ [ assume ( x > 0 ) ] ] ; 。该语句被称为 假设语句

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

  • 若转换后的 表达式 在假设出现的位置将求值为 true ,则该假设不产生任何效果。
  • 否则,该假设的求值将引发 运行时未定义行为

注释

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

使用它们的一种正确方式是让假设紧随断言:

assert(x > 0);     // 当未定义 NDEBUG 且 x > 0 为假时触发断言
[[assume(x > 0)]]; // 当定义 NDEBUG 时提供优化机会

示例

#include <cmath>
void f(int& x, int y)
{
    void g(int);
    void h();
    [[assume(x > 0)]]; // 编译器可假定 x 为正数
    g(x / 2); // 可能生成更高效的代码
    x = 3;
    int z = x;
    [[assume((h(), x == z))]]; // 编译器可假定调用 h 后 x 保持原值
                               // 该假设不会实际调用 h
    h();
    g(x); // 编译器可能将其替换为 g(3)
    h();
    g(x); // 编译器不可将其替换为 g(3)
          // 假设仅在其出现的位置生效
    z = std::abs(y);
    [[assume((g(z), true))]]; // 编译器可假定 g(z) 会正常返回
    g(z); // 基于上下文的假设,编译器可能将其替换为 g(10)
    [[assume(y == -10)]]; // 若此时 y != -10 则行为未定义
    [[assume((x - 1) * 3 == 12)]];
    g(x); // 编译器可能将其替换为 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(...)))