assert
来自cppreference.com
在标头 <cassert> 定义
|
||
禁用的断言 |
||
(1) | ||
#define assert(condition) ((void)0) |
(C++26 前) | |
#define assert(...) ((void)0) |
(C++26 起) | |
启用的断言 |
||
(2) | ||
#define assert(condition) /* 未指定 */ |
(C++26 前) | |
#define assert(...) /* 未指定 */ |
(C++26 起) | |
宏 assert
的定义依赖于标准库中没有定义的另一个名为 NDEBUG 的宏。
2) 否则断言会启用:
|
(C++26 前) |
|
(C++26 起) |
诊断信息的格式由实现定义,但它始终会包含以下信息:
|
(C++26 前) |
|
(C++26 起) |
如果满足以下条件之一,那么表达式 assert(E) 保证是常量子表达式:
|
(C++11 起) |
目录 |
[编辑] 参数
condition | - | 标量类型的表达式 |
[编辑] 注解
因为 assert(std::is_same_v<int, int>); // 错误:assert 不接收两个参数 assert((std::is_same_v<int, int>)); // OK:一个实参 static_assert(std::is_same_v<int, int>); // OK:不是宏 std::complex<double> c; assert(c == std::complex<double>{0, 0}); // 错误 assert((c == std::complex<double>{0, 0})); // OK |
(C++26 前) |
没有标准化的添加消息到 assert
错误的接口。一个包含它的方式是使用逗号运算符,只要它未被重载,或者和字符串字面量一起使用 &&
:
assert(("有五盏灯", 2 + 2 == 5)); assert(2 + 2 == 5 && "有五盏灯");
assert
在 Microsoft CRT 中的实现不遵从 C++11 以及后续标准版本,因为它的底层函数(_wassert
)不接收 __func__ 或等价的替代品。
从 C++20 开始,诊断信息所需的值也可以通过 std::source_location::current() 获取。
虽然 C23/C++26 中 assert
的更改不是正式的缺陷报告, C 委员会推荐实现将该更改向后移植到旧模式。
[编辑] 示例
运行此代码
#include <iostream> // 去注释以禁用 assert() // #define NDEBUG #include <cassert> // 使用 (void) 关闭“未使用”警告 #define assertm(exp, msg) assert((void(msg), exp)) int main() { assert(2 + 2 == 4); std::cout << "检查点 #1\n"; assert((void("void 可以避免“未使用值”警告"), 2 * 2 == 4)); std::cout << "检查点 #2\n"; assert((010 + 010 == 16) && "另一种添加断言信息的方式"); std::cout << "检查点 #3\n"; assertm((2 + 2) % 3 == 1, "成功"); std::cout << "检查点 #4\n"; assertm(2 + 2 == 5, "失败"); // 断言失败 std::cout << "在最后一个断言后继续执行\n"; // 不会输出 }
可能的输出:
检查点 #1 检查点 #2 检查点 #3 检查点 #4 main.cpp:23: int main(): Assertion `((void)"失败", 2 + 2 == 5)' failed. Aborted
[编辑] 缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 2234 | C++11 | assert 无法在常量表达式中使用
|
可以使用 |
[编辑] 参阅
contract_assert 语句 (C++26)
|
在执行中验证一项内部条件 |
static_assert 声明 (C++11)
|
进行编译时断言检查 |
导致非正常的程序终止(不进行清理) (函数) | |
assert 的 C 文档
|