首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++之assert惯用法

  • 25-02-17 10:01
  • 4669
  • 13128
blog.csdn.net

目录

1.引言

2.简单示例

3.推荐使用方法

4.常见使用场景和注意事项

4.1.检查参数的合法性

4.2.assert不能使用改变环境的语句

4.3.在未知的逻辑中添加assert(false)

5.总结


1.引言

        assert在  头文件中定义,其作用是如果它的提交呢返回错误,则终止执行。

        原型定义:

  1. #include
  2. void assert(int expression);

        assert的作用是先计算表达式expression,如果其值为假(即为0),那么它向stderr打印一条错误信息,然后通过调佣abort来终止程序运行。

        通常,它用于检查在程序执行过程中应始终为真的条件。即当违反真理时, 触发断言. 比如1+1=2,当1+1≠2时触发断言。比如,

  1. assert(false); // 中断程序;
  2. assert(0 && "the code is error!"); // 中断并打印信息

2.简单示例

  1. #include // header
  2. int divide(int numerator, int denominator) {
  3. assert(denominator != 0); // 确保分母不为零
  4. return numerator / denominator;
  5. }
  6. int main() {
  7. int result = divide(10, 2);
  8. // ...
  9. return 0;
  10. }

        在上面的示例中,assert 宏确保分母永远不为零。如果分母为零,程序将以指示文件名、行号和失败的表达式的错误消息终止。

3.推荐使用方法

经常在C++程序中,以便于在开发过程中进行断言检查,而在发布版本中则禁用这些检查。

推荐写成如下方式,编写一个assert_utils.h文件,内容如下:

  1. #pragma once
  2. #ifndef RELEASE
  3. #include
  4. #define ASSERT(f) assert(f)
  5. #else
  6. #define ASSERT(f) ((void)0)
  7. #endif

下面是对这段代码的解释:

1) #pragma once:这是一个预处理指令,用于确保头文件只被包含一次。它的效果取决于编译器,但大多数现代编译器都支持它。

2) #ifndef RELEASE:这是一个预处理指令,用于检查是否定义了RELEASE宏。如果没有定义,编译器将继续执行下面的代码块。

3) #include :如果RELEASE宏没有定义,编译器将包含cassert头文件,这是标准C++库的一部分,提供了assert宏。

4) #define ASSERT(f) assert(f):定义了一个宏ASSERT,它接受一个表达式f作为参数。当ASSERT被调用时,它将执行assert(f),如果f为假(即表达式结果为0),程序将终止运行,并显示一个断言失败的消息。

5) #else:如果RELEASE宏被定义,编译器将跳过上面的代码块,执行下面的代码。

6) #define ASSERT(f) ((void)0):在发布版本中,ASSERT宏被定义为一个空操作,即什么都不做。这样,在发布版本的程序中,所有ASSERT调用都不会执行任何操作,从而避免了性能损耗和潜在的程序中断。

7) #endif:结束#ifndef RELEASE条件编译块。

4.常见使用场景和注意事项

4.1.检查参数的合法性

示例如下:

  1. int sendData(const char* pData, int len)
  2. {
  3. //[1] 校验参数的合法性
  4. assert(pData);
  5. assert(len > 0)
  6. //[2]
  7. //...
  8. }

每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败,如:

assert(pData && len > 0);  //这样不好

4.2.assert不能使用改变环境的语句

因为assert只在DEBUG环境中生效,如果这么做,会导致DEBUG和RELEASE的逻辑不一致。如:

assert(i++ < 100);

在DEUG环境下,每次都会执行i++,而在RELEASE环境中不会执行i++,这样就会导致两种环境下的执行结果不一样,正确的写法是:

  1. assert(i < 100);
  2. i++;

4.3.在未知的逻辑中添加assert(false)

如:

  1. //根据业务类型处理业务
  2. void dealPro(int type)
  3. {
  4. if (type == 0){
  5. // 文本业务
  6. }else if (type == 1){
  7. // 地图业务
  8. }else if (type == 2){
  9. // 测试业务
  10. }else{
  11. assert(false);
  12. }
  13. }

        上述代码,我们的业务逻辑只涉及到文本、地图、测试业务,其它的都是非法业务,添加assert(false),一旦type不等与1、2、3,就会出现断言错误,查看程序堆栈,这样就非常快速的定位程序是哪个地方出现逻辑错误了,这个也是一个非常好的调试技巧。

5.总结

        总之,assert是一种在开发过程中快速检测程序错误的有效工具,但在发布的产品代码中通常被禁用以避免性能影响。开发者可以根据需要使用assert或其他错误处理机制来确保程序的正确性和健壯性。

注:本文转载自blog.csdn.net的流星雨爱编程的文章"https://blog.csdn.net/haokan123456789/article/details/139607725"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top