Zed的强大的调试宏

#为什么需要错误处理

大多数程序员假定错误不会发生,并且这一乐观的思想影响了他们所用和创造的语言。

C通过返回错误码或设置全局的errno值来解决这些问题,并且你需要检查这些值。
通过这种机制检查现存的复杂代码中,你所执行的东西是否发生错误。模式如下

  • 调用函数
  • 如果返回值出现错误(每次必须检查)
  • 清理创建的所有资源
  • 打印出所有可能有帮助的错误信息

接下来将专注于这些步骤的实现

实现错误机制意味着每个函数调用结束后都需要3~4行额外代码,太麻烦。使用一系列“调试宏”作为解决方案。

几个重要的认知:

  • 错误检查可以在代码里直接写出,不过通常需要3~4行
  • 利用宏(而不是函数)来实现是由许多优势的
    • 简洁
    • 错误处理时需要用到file:line信息,如果在函数内部执行这些会得到错误信息
    • goto函数的实现会相当麻烦
  • goto 可以和标签结合使用
  • 宏的使用也有相当多的技巧,与函数有异曲同工之妙,但在使用方式上更加灵活(某些方面)

宏定义

#ifndef __dbg_h__
#define __dbg_h__#include <stdio.h>
#include <errno.h>   //引入errno变量
#include <string.h>#ifdef NDEBUG       //可以通过宏定义来消除所有调试信息
#define debug(M, ...)
#else
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)//输出错误信息,文件名,行号等。其中:##__VA_ARGS__表示宏中...   可以类似调用printf使用debug
#endif#define clean_errno() (errno == 0 ? "None" : strerror(errno))#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }#define sentinel(M, ...)  { log_err(M, ##__VA_ARGS__); errno=0; goto error; }#define check_mem(A) check((A), "Out of memory.")#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }#endif

代码解释

<errno.h>头文件

errno不是一个库,而是一个全局变量。
当调用一些系统库函数时,他们可能会设置errno的值来指示错误的类型。
通常,成功完成函数调用时会置零。
使用实例

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>int main() {FILE *file = fopen("nonexistent_file.txt", "r");if (file == NULL) {perror("Error opening file");    //自动根据error输出错误信息,终端显示:Error opening file: No such file or directoryfprintf(stderr, "errno = %d\n", errno);  //输出到标准输出流,终端显示:error = xexit(EXIT_FAILURE);}// Use the file...fclose(file);return 0;
}

综上理解:errno是一个全局变量,可以用来获取函数执行失败后的错误信息代号。
通常搭配perrorfprintf(stderr, " xxx%dxxx " , errno)使用

debug宏

#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)

输出错误信息到终端:__FILE__代表文件名,__LINE__代表行号,##__VA_ARGS__代表可变参数部分...
这里对于debug的使用类似于调用printf

  • M是想要输出的错误字符串,注意不带换行符。
  • 后续可变参数可以替换M 中格式化预留的内容。

实例:
debug("I am %d years old.", 37);
终端输出
DRBUG ex20.c:11: I am 37 years old

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE学习笔记 Day18

JavaSE学习笔记 Day18 个人整理非商业用途&#xff0c;欢迎探讨与指正&#xff01;&#xff01; 上一篇 文章目录 JavaSE学习笔记 Day1816.2.2迭代器16.2.3泛型的基本使用 16.3常见的单列集合实现类16.3.1ArrayList16.3.2List集合的遍历16.3.3ArrayList的底层实现16.3.4Linked…

Spark编程实验二:RDD编程初级实践

目录 一、目的与要求 二、实验内容 三、实验步骤 1、pyspark交互式编程 2、编写独立应用程序实现数据去重 3、编写独立应用程序实现求平均值问题 4、三个综合实例 四、结果分析与实验体会 一、目的与要求 1、熟悉Spark的RDD基本操作及键值对操作&#xff1b; 2、熟悉使…

Linux-----21、挂载

# 挂载命令 将硬件资源&#xff0c;或文件资源&#x1f4bf;&#xff0c;和&#x1f4c2;空目录&#x1f517;连接起来的过程 # mount linux 所有存储设备都必须挂载使用&#xff0c;包括硬盘 ​ 命令名称&#xff1a;mount ​ 命令所在路径&#xff1a;/bin/mount ​ 执行…

得帆信息创始人-张桐,受邀出席 BV百度风投AIGC主题论坛

近日&#xff0c;得帆信息创始人兼CEO张桐&#xff0c;作为百度风投被投代表企业创始人受邀出席“向未来&#xff0c;共成长” BV百度风投AIGC主题论坛。 与包括上海市徐汇区相关部门领导、百度集团相关事业部负责人及代表&#xff0c;以及来自国寿资本、中网投、麦顿投资的投资…

如何让32位.Net 应用打开3G开关

昨天刚分享了《如何让.NET应用使用更大的内存》&#xff0c;结果就有同学说&#xff0c;<最好加一下32位如何开启大内存&#xff0c;因为很多传统项目32位&#xff0c;实在迁移不动了>&#xff0c;那么&#xff0c;我就验证了一些可行的方案&#xff0c;发现都挺简单的。…

内网安全—Windows系统内核溢出漏洞提权

系统内核溢出漏洞提权 往缓冲区中写入超出限定长度的内容&#xff0c;造成缓冲区溢出&#xff0c;从而破坏程序的堆栈进而运行自己精心准备的指定代码&#xff0c;达到攻击的目的。 分类&#xff1a; 堆溢出 栈溢出 查找补丁的方法 1、手工查找补丁情况 systeminfo Wmic qfe…

CGAL和求解器

几个CGAL包必须解决稠密或稀疏矩阵的线性系统、线性整数规划和二次规划。这个包为此提供了概念和模型。 对于线性系统&#xff0c;我们通常使用Eigen库提供模型。 Eigen类Eigen_matrix和Eigen_vector的封装器也在需要时提供。为其他求解器开发等效模型很简单&#xff0c;例如在…

在Django中使用多语言(i18n)

在Django中使用多语言 配置中间件 MIDDLEWARE [......django.contrib.sessions.middleware.SessionMiddleware,django.middleware.locale.LocaleMiddleware, # 此行重点django.middleware.common.CommonMiddleware,...... ]配置翻译文件目录 根目录下创建目录locale # 国…

Cmake基础(5)

这篇文章主要描述如何使用cmake构建一个库工程 文章目录 add_libraryinstall 库工程的代码&#xff1a;头文件和源文件 #ifndef ADD_H #define ADD_H#ifdef _WIN32 #ifdef MYMATH_EXPORTS #define MYMATH_API __declspec(dllexport) #else #define MYMATH_API __declspec(dll…

CopyOnWriteArrayList(一)

1 CopyOnWriteArrayList介绍 CopyOnWriteArrayList是一个线程安全的ArrayList。 CopyOnWriteArrayList是基于lock锁和数组副本的形式去保证线程安全。 在写数据时&#xff0c;需要先获取lock锁&#xff0c;需要复制一个副本数组&#xff0c;将数据插入到副本数组中&#xff0c…

Semaphore学习一

一、定义 是JUC包下的一个工具类&#xff0c;我们可以通过其限制执行的线程数量&#xff0c;达到限流的效果。 当一个线程执行时先通过其方法进行获取许可操作&#xff0c;获取到许可的线程继续执行业务逻辑&#xff0c;当线程执行完成后进行释放许可操作&#xff0c;未获取达到…

Python 全栈体系【四阶】(七)

第四章 机器学习 六、多项式回归 1. 什么是多项式回归 线性回归适用于数据呈线性分布的回归问题。如果数据样本呈明显非线性分布&#xff0c;线性回归模型就不再适用&#xff08;下图左&#xff09;&#xff0c;而采用多项式回归可能更好&#xff08;下图右&#xff09;。例…

数据安全传输基础设施平台(二)

5安全传输平台总体设计 5.1 方案特点 规范化&#xff1a;严格遵循各种相关规范设计。独立性&#xff1a;系统各子系统间互相独立&#xff0c;在保持系统间接口的前提下&#xff0c;各系统间的升级互不干扰。最小耦合性&#xff1a;各子系统进行严格功能分解&#xff0c;每个子…

PCL点云处理之点云置平(拟合平面绕中心旋转到绝对水平)(二百二十七)

PCL点云处理之点云置平(绕中心旋转到绝对水平)(二百二十七) 一、什么是点云置平二、算法流程三、算法实现一、什么是点云置平 有时候,我们处理的点云平面并非位于水平面,而是位于某个任一三维平面上,而大多数算法又只能在水平面处理,或者水平面的点云处理是相对更简单…

P2P应用

目录 一.P2P的简介 二.P2P的工作方式 1.具有集中目录服务器的P2P工作方式 2.具有全分布式结构的P2P文件共享程序 一.P2P的简介 P2P(对等连接)&#xff0c;是指两台主机在通信时&#xff0c;并不区分哪一个是服务请求方和哪一个是服务提供方。只要两台主机都运行了对等连接…

人工智能_机器学习069_SVM支持向量机_网格搜索_交叉验证参数优化_GridSearchCV_找到最优的参数---人工智能工作笔记0109

然后我们再来说一下SVC支持向量机的参数优化,可以看到 这次我们需要,test_data这个是测试数据,容纳后 train_data这个是训练数据 这里首先我们,导出 import numpy as np 导入数学计算包 from sklearn.svm import SVC 导入支持向量机包 分类器包 def read_data(path): wit…

ping: unknown host www.baidu.com

您遇到的问题表明系统无法解析 “www.baidu.com” 的域名。这通常与 DNS&#xff08;域名系统&#xff09;配置或网络连接问题有关。以下是一些解决步骤&#xff1a; 1. 检查网络连接 首先确保您的系统已连接到互联网。您可以尝试 ping 一些知名的网站或使用 IP 地址来测试连…

从事开发近20年,经历过各种技术的转变和进步

1、jsp、javabean、servlet、jdbc。 2、Struts1、hibernate、spring。 3、webwork、ibatis、spring 4、Struts2、mybatis、spring 5、spring mvc &#xff0c;spring全家桶 6、dubbo&#xff0c;disconf 微服务&#xff0c;soa 7、springboot 全家桶 8、docker 9、dock…

qt使用事件来进行文件操作

使用键盘进行操作 #include<QKeyEvent> 包含的头文件 在.h文件中添加此函数 void keyPressEvent(QKeyEvent*k); 在.cpp中的实现操作 void MainWindow::keyPressEvent(QKeyEvent*k) {if(k->modifiers()Qt::ControlModifier&&k->key()Qt::Key_S){saveAc…

AXure的情景交互

目录 导语&#xff1a; 1.erp多样性登录界面 2.主页跳转 3.省级联动​编辑 4. 下拉加载 导语&#xff1a; Axure是一种流行的原型设计工具&#xff0c;可以用来创建网站和应用程序的交互原型。通过Axure&#xff0c;设计师可以创建情景交互&#xff0c;以展示用户与系统的交…