C语言学习之assert
C语言学习之assert
assert (编程术语)
编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。C语言中assert的用法
assert是宏,而不是函数。在C的assert.h头文件中。
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行。
assert的细节是先计算表达式expr,如果其值为假(即为0),那么它会打印出来assert的内容和__FILE__, LINE, __ASSERT_FUNCTION,然后执行abort()函数使kernel杀掉自己并coredump(是否生成coredump文件,取决于系统配置);否则,assert()无任何作用。例1的程序清单assert0case.c
1)assert0case.c的程序
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
struct ITEM
{
int key;
int value;
};
/*add item to list,make sure list is not null*/
/*添加一个项目到列表中,列表不能为空*/
void additem(struct ITEM* itemptr)
{
assert(itemptr!=NULL);
/*add item to list*/
/*添加项目之列表中,使用了assert*/
}
int main(void)
{
additem(NULL);
/*插入空指针,程序会报错*/
return 0;
}
2)执行的结果
[zsd@localhost ~]$ gcc ./assert0case.c -o assert0case
[zsd@localhost ~]$ ./assert0case
assert0case: ./assert0case.c:12: additem: Assertion `itemptr!=((void *)0)' failed.
/*可以看到代码12行出现了问题,想插入NULL,但是列表不让*/
Aborted (core dumped)
- 例2的程序清单assert0case1.c
1)assert0case1.c的程序
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
int main(void){
FILE* fp;
fp=fopen("test.txt","w");//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert(fp);//所以这里不会出错
fclose(fp);
fp=fopen("noexitfile.txt","r");//以只读的方式打开一个文件,如果不存在就打开文件失败
assert(fp);//所以这里出错
fclose(fp);//程序永远都执行不到这里来
return 0;
}
2)执行的结果
[zsd@localhost ~]$ gcc ./assert0case1.c -o assert0case1
[zsd@localhost ~]$ ./assert0case1
assert0case1: ./assert0case1.c:10: main: Assertion `fp' failed.
/*可以看到代码第10行出现了问题,想打开noexitfile.txt的文件,但是没有,所以C语言报错*/
Aborted (core dumped)
/分割线***/
以上实验的目的,看MySQL内核的源码。很多地方用到了如下语句。
源代码的位置在fut/fut0lst.cc
.发现多次使用了ut_ad
语句。
/********************************************************************//**
Adds a node to an empty list. */
static
void
flst_add_to_empty(
/*==============*/
flst_base_node_t* base, /*!< in: pointer to base node of
empty list */
flst_node_t* node, /*!< in: node to add */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
ulint len;
ut_ad(mtr && base && node);
ut_ad(base != node);
/*这里多次用到了ut_ad语句,可以查看include/ut0dbg.h文件*/
ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr_memo_contains_page(mtr, node, MTR_MEMO_PAGE_X_FIX));
len = flst_get_len(base, mtr);
ut_a(len == 0);
buf_ptr_get_fsp_addr(node, &space, &node_addr);
/* Update first and last fields of base node */
flst_write_addr(base + FLST_FIRST, node_addr, mtr);
flst_write_addr(base + FLST_LAST, node_addr, mtr);
/* Set prev and next fields of node to add */
flst_write_addr(node + FLST_PREV, fil_addr_null, mtr);
flst_write_addr(node + FLST_NEXT, fil_addr_null, mtr);
/* Update len of base node */
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
在分析include/ut0dbg.h
文件,发现ut_ad语句的声明如下:
#ifdef UNIV_INNOCHECKSUM
#define ut_a assert /*全部都是assert断言*/
#define ut_ad assert
#define ut_error assert(0)
#else /* !UNIV_INNOCHECKSUM */
#ifdef UNIV_DEBUG
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) do {EXPR;} while (0)
#else
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR)
#endif
C语言学习之assert的更多相关文章
- Groovy语言学习--语法基础(1)
2018年11月末,从上家公司离职后进入现在的公司.进入项目以来,发现项目中有很多groovy脚本,以前没接触过groovy,抽时间系统地学一下,也方便后期项目的开发和维护. groovy和java的 ...
- 【转】朱兆祺教你如何攻破C语言学习、笔试与机试的难点(连载)
原文网址:http://bbs.elecfans.com/jishu_354666_1_1.html 再过1个月又是一年应届毕业生应聘的高峰期了,为了方便应届毕业生应聘,笔者将大学四年C语言知识及去年 ...
- Dart语言学习(十) Dart流程控制语句
一.条件语句:if.if...elseif.if...elseif...else int score = 95; if (score >=90) { print('优秀'); } else if ...
- C语言学习 第八次作业总结
本次作业其实没有新的内容,主要就是复习上一次的一维数组的相关内容.冯老师布置了5道题目,其中涉及到一些比较简单的排序或者是查找的方法.因为数据很少,所以直接使用for循环遍历就可以了. 关于本次作业, ...
- C语言学习 第七次作业总结
C语言学习 第七次作业总结 数组可以分为数组和多下标数组(在传统的国内C语言书本中,将其称为二/多维数组). 数组名称 在之前的课程中,大家应该都有印象,对于int a这样的定义,会为变量 a 声明一 ...
- 技能收获与C语言学习
你有什么技能比大多人(超过90%以上)更好? 我会的东西很多,喜欢的东西太多,但是很遗憾广而不专,会而不精.学了很多东西我都是为了娱乐,因为以前我们那里过于强调学习,很多爱好也都被扼杀在摇篮里.我觉得 ...
- 一份关于Swift语言学习资源的整理文件
一份关于Swift语言学习资源的整理文件 周银辉 在这里下载 https://github.com/ipader/SwiftGuide
- go语言学习笔记
Go语言学习基本类型Bool 取值范围:true,false (不可以用数字代替)Int/uint 根据平台可能为32或64位int8/uint8 长度:1字节 取值范围-128~127/0~255b ...
- 20155206赵飞技能获取经验,C语言学习感想与对JAVA的学习目标
自己较强的技能获取经验. 1:实话实说我自己是没有哪个技能可以超过90%的人的,只有自认为做的还可以的一些事情,例如打篮球,office软件的应用,一百米跑.至于其他方面就是很平庸了. 2:经验主要有 ...
随机推荐
- linux时区和时间设置
1,修改时区 调整时区使用tzselect [root@lyn ~]# hwclock Tue Nov :: PM AST -0.198205 seconds [root@lyn ~]# tzsele ...
- ABAP 常见系统表
TRDIRT Program nameTFTIT Function module nameDD02T Table name
- Mac下git配置
1.下载git 2.配置key macdeMacBook-Pro:~ mac$ cd ~/.ssh macdeMacBook-Pro:.ssh mac$ ssh-keygen -t rsa -C &q ...
- 学习Python第六天
今天我们讲讲数据类型中的集合,博客写得有点糙,后续应该要进行优化优化了........ 集合:无序,不重复的数据组合,主要作用:去重,把一个列表变成集合,就自动去重了 基本语法:S = {1}类型为集 ...
- Reids学习1 -- 初识Redis
1. Reids和其他类型数据库对比 名称 类型 数据库存储选项 查询类型 附加功能 Redis 使用内存存储的非关系数据库 字符串,列表,集和,散列表,有序集合 每个类型有自己的专属命令,还有批量操 ...
- QEMU KVM libvirt 手册(3) - Storage Media
访问Hard Drive 使用-hda –hdb qemu-system-x86_64 -enable-kvm -name ubuntutest -m 2048 -hda ubuntutest.im ...
- VSCode插件开发全攻略(九)常用API总结
更多文章请戳VSCode插件开发全攻略系列目录导航. 本文提炼一些常见的API使用场景供参考,本文内容有待完善. 编辑器相关 修改当前激活编辑器内容 替换当前编辑器全部内容: vscode.windo ...
- feign调用spring clound eureka 注册中心服务
@RestController public class TestService { private TestApi computeClient; private static final Strin ...
- str2-045漏洞事件,你想要的这里都有
话说昨天一觉醒来,发现整个安全圈被一个名为str2-045的漏洞霸屏了,好多小伙伴已经开始了喜刷刷的艰苦奋斗过程.然而对于很多小白童鞋来讲,他们可能还是处于懵逼的状态,别急,咱们专门为你们做了一期专题 ...
- Javascript高级编程学习笔记(61)—— 事件(5)UI事件
UI事件 UI事件是指那些不一定与用户操作有关的事件 这些事件在DOM规范出现之前,都是以各种不同的形式存在于不同的浏览器 而在DOM事件中为了保证向后兼容,现有的UI事件如下: DOMActivat ...