assert(断言)

断言assert是一个宏,该宏在<assert>中,,当使用assert时候,给他个参数,即一个判读为真的表达式。预处理器产生测试该断言的代码,如果断言不为真,则发出一个错误信息告诉断言是什么以及它失败一会,程序会终止。 
我们一般可以用在判断某件操作是否成功上。
摘录林锐博士高质量编程一书中相关内容。

~~~~~~~~~~~~~~~~~~~~~~~~
程序一般分为Debug版本和Release版本,Debug版本用于内部调试,Release版本发行给用户使用。 
断言assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生的情况。以下是一个内存复制程序,在运行过程中,如果assert的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。 
//复制不重叠的内存块 
void memcpy(void *pvTo, void *pvFrom, size_t size) 
{ 
void *pbTo = (byte *) pvTo; 
void *pbFrom = (byte *) pvFrom; 
assert( pvTo != NULL && pvFrom != NULL ); 
while(size - - > 0 ) 
*pbTo + + = *pbFrom + + ; 
return (pvTo); 
} 
assert不是一个仓促拼凑起来的宏,为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。 
以下是使用断言的几个原则: 
1)使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。 
2)使用断言对函数的参数进行确认。 
3)在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。 
4)一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。
### 3.1 `assert` 断言的使用方法 `assert` 是一种在程序运行时进行调试检查的机制,用于验证某个条件是否为真。如果条件为假(即表达式结果为 0),程序将输出错误信息并终止执行。这种机制在调试阶段非常有用,可以帮助开发者快速定位违反前提条件的错误。 在 C++ 中,`assert` 宏定义在 `<cassert>` 或 `<assert.h>` 头文件中,其基本语法如下: ```cpp assert(expression); ``` 其中 `expression` 是一个布尔表达式,若为假(即值为 0),程序将中止并打印错误信息。 例如,用于检查函数参数的有效性: ```cpp #include <iostream> #include <cassert> char* arrayAlloc(int n) { assert(n > 0); // 如果 n <= 0,则程序在此处中止 return new char[n]; } int main() { char* a = arrayAlloc(-1); // 触发断言失败 return 0; } ``` 在调试过程中,上述代码会因 `n <= 0` 而触发断言失败,从而中止程序执行,防止进入不合理的逻辑路径[^2]。 此外,某些实现允许在 `assert` 后添加自定义信息,格式如下: ```cpp assert(expression && "Error message"); ``` 这种方式可以增强错误信息的可读性,帮助开发者更快定位问题[^1]。 --- ### 3.2 常见问题与注意事项 1. **断言只在调试模式下生效** 在 C++ 中,`assert` 宏在定义了 `NDEBUG` 宏时会被忽略。因此,在发布版本中,所有 `assert` 检查将被移除。这意味着不能依赖 `assert` 来处理运行时错误或异常。 2. **避免在 `assert` 中执行有副作用的操作** 由于 `assert` 可能在发布版本中被移除,因此不应在其表达式中调用可能影响程序行为的函数或修改变量。例如: ```cpp assert(getValue() > 0); // 若 getValue() 有副作用,可能在发布版本中导致行为不一致 ``` 3. **断言表达式应为纯逻辑判断** `assert` 的表达式应当仅用于逻辑判断,不应包含资源释放、状态变更等操作。例如: ```cpp assert(deleteResource()); // 不推荐,deleteResource() 在发布版本中不会执行 ``` 4. **断言失败后的行为不可恢复** 一旦断言失败,程序将终止执行。因此,`assert` 不适用于可恢复的错误处理,如用户输入错误或文件读取失败等。 5. **合理使用断言信息提示** 可以通过在断言中添加字符串信息来增强调试提示,例如: ```cpp assert(value >= 0 && value <= 100 && "Value must be in range [0, 100]"); ``` 这种方式有助于在断言失败时提供更清晰的上下文信息[^1]。 --- ### 3.3 与 `EXPECT_CALL` 的对比 虽然 `assert` 和 `EXPECT_CALL` 都用于验证程序行为,但它们的用途和机制有所不同。`assert` 用于验证程序运行时的前置条件,适用于函数参数检查、状态一致性验证等场景。而 `EXPECT_CALL` 是 Google Mock 框架的一部分,用于在单元测试中定义对模拟对象的期望调用行为,包括调用次数、参数匹配和返回值等。 例如,`EXPECT_CALL` 可以验证某个方法是否被调用指定次数并传入特定参数,而 `assert` 更适用于函数内部的状态检查。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值