C++ attribute: assume (since C++23)
| 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 | ||||||||||||||||
|
||||||||||||||||
| 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 | ||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
assume
(C++23)
|
||||
|
(C++11)
(until C++26)
|
||||
|
(C++14)
|
||||
|
(C++17)
|
||||
|
(C++26)
|
||||
|
(C++20)
|
||||
|
(C++17)
|
||||
|
(C++17)
|
||||
|
(C++11)
|
||||
|
(C++20)
|
||||
|
(TM TS)
|
||||
|
(C++20)
|
指定在给定点假定表达式始终求值为 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]
参见
|
(C++23)
|
标记不可达的执行点
(函数) |
contract_assert
语句
(C++26)
|
在执行期间验证内部条件 |
外部链接
| 1. |
Clang 语言扩展文档:
__builtin_assume
。
|
| 2. |
Clang 属性参考文档:
assume
。
|
| 3. |
MSVC 文档:
__assume
内置函数。
|
| 4. |
GCC 文档:
__attribute__((assume(...)))
。
|