C语言错误处理

学习C++的时候就没有怎么重视异常这部分知识,后来知道也基本没有看到C++项目里面用try/catch的。google编程规范中甚至直接说明不使用C++这个特性,所以我一直都没搞明白这个“简单的”try/catch。

查阅《C++编程思想》,我记录以下一些内容。首先是C语言的一些错误处理方法。

1) 出错信息可通过函数的返回值获得。如果函数返回值不能用,则可设置一全局错误判断标志(标准 C语言中 errno( )和perror( )函数支持这一方法)。由于对每个函数调用都进行错误检查,这十分繁琐并增加了程序的混乱度。程序设计者可能简单地忽略这些出错信息,因为乏味而迷乱的错误检查必须随着每个函数调用而出现。另外,来自偶然出现异常的函数的返回值可能并不反映什么问题。这中方法异常处理方法在Linux内核里面非常见,甚至可以说是标准的做法。根据函数的返回值判断函数的执行结果,再结合一大堆的goto语句,实现错误处理(比如说资源的释放)。比较常见的是资源申请的情况,如果资源数量比较多,就会出现程序逻辑复杂。goto语句很容易就把你搞得头大。

2) 可使用 C标准库中一般不太熟悉的信号处理系统,利用signal()函数(判断事件发生的类型)和raise()函数(产生事件)。由于信号产生库的使用者必须理解和安装合适的信号处理系统,所以应紧密结合各信号产生库,但对于大型项目,不同库之间的信号可能会产生冲突。这种方法的缺陷更明显了,用户信号是有限的,虽然可以更换处理函数。但是冲突是几乎不可避免的,你怎么知道会不会有两个错误同时发生了,结果有一个错误信号就被忽略了。

3) 使用 C标准库中非局部的跳转函数: setjmp( ) 和 longjmp( )。 setjmp( ) 函数可在程序中存储一典型的正常状态,如果进入错误状态, longjmp( )可恢复setjmp( ) 函数的设定状态,并且状态被恢复时的存储地点与错误的发生地点紧密联系。说实话我貌似是第一次明白这东西的作用,汗!(不过现在习惯了,std::bind什么的现在也都不知道!)。下面是一个例子:其实就是抄了下书上的代码。

#include <iostream>
#include <setjmp.h>

using namespace std;
class rainbow {
public:
    rainbow() { cout<<"rainbow()"<<endl;
              }
    ~rainbow() {
        cout<<"~rainbow()"<<endl;
    }
};

jmp_buf kansas;
void OZ()
{
    rainbow RB;
    for(int i=0;i<3;i++)
    {
        cout<<"there is no place like home\n";
    }
    longjmp(kansas, 47);
    //这里的value是回到setjmp位置时,setjmp的返回值。如果设置为0,则返回值是1
}

int main()
{
    if(setjmp(kansas) == 0) {
        cout<<"tornado, witch, munchkins...\n";
        OZ();
    }else {
        cout<< "Auntie Em! "
            << "I had the strangest dream...\n"
            <<endl;
    }
}

至于C++的异常语法,其实大家都是知道的。但是它是如何实现的呢?这一直是一个疑问。后来我看了白杨的《C++异常机制的实现方式和开销分析》传送门,确实有茅塞顿开的感觉,推荐一下。

时间: 2024-12-30 05:34:57

C语言错误处理的相关文章

C语言-错误处理

标记程序的运行状态和控制主要有以下几种:break/continue/return/参数的返回值/exit(int n)_exit() atexit((*p)(参数列表)): 1 break:用在开关语句.循环语句.和if结合使用.表示跳出当前开关.循环体(仅跳出一层),执行开关循环体后面的程序,和if结合使用表示满足条件则结束循环.注意break对if else不起作用,在多次循环中只能跳出一层. 2 continue:用在循环体.和if配套使用.表示结束本轮循环强制进行下一轮循环.和if结合

Go语言开发(七)、Go语言错误处理

Go语言开发(七).Go语言错误处理 一.defer延迟函数 1.defer延迟函数简介 defer在声明时不会立即执行,而是在函数return后,再按照FILO(先进后出)的原则依次执行每一个defer,一般用于异常处理.释放资源.清理数据.记录日志等.每次defer语句执行时,defer修饰的函数的返回值和参数取值会照常进行计算和保存,但是defer修饰的函数不会执行.等到上一级函数返回前,会按照defer的声明顺序倒序执行全部defer的函数.defer所修饰函数的任何返回值都会被丢弃.如

C语言错误:request for member ‘xxx’ in something not a structure or union

今天在编译一个C语言程序时,对于结构体变量,报出错误 Error: request for member 'xxx' in something not a structure or union. 经过调试发现是 . 与 -> 搞错了. 如果它是地址,就在它后边用 ->,如果它不是地址,就在它后边就用 . 代码举例简略如下: #include <stdio.h> #include <string.h> typedef struct Test_t { char name[2

极品的C语言错误

今天在测试硬件通信模块时候发现一个奇怪的问题,发送数据和接收数据进行比较复制时候频繁数据错误. 测试流程如下:发送一个字节和接收一个字节,进行比较,当返回数据和发送数据不相等的时候,错误计数器累加. 数据收发抽象如下: uint16 i = 0; uint16 j = 0; uint32 error_num = 0; XX_send_data(i++); j = XX_rece_data(); if(i != (j + 1)) { error_num++; } 这段代码按照理论上来说,只要发送数

C语言错误: CRT detected that the application wrote to memory after end of heap buffer

CRT detected that the application wrote to memory after end of heap buffer 多是中间对其进行了一些操作,在程序结束处,释放内存的时候,引起错误: HEAP CORRUPTION DETECTED:after Normal block(#***) at 0x****.CRT detected that application wrote memory after end of heap buffer. 错误原因: 以对内在操

C语言错误: HEAP CORRUPTION DETECTED

程序源代码: //写文件两种方式(文本文件和二进制文件) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> //文本写文件 int writeWord(const char *path,const char *pword){ int ERRO_MSG = 0; if (path == NULL) { ERRO_MSG = 1; printf(&q

Go语言错误处理小例子

满屏的error处理会是个悲剧,也不利于对错误进行区分处理. 建议在项目中多用自定义错误,再对错误集中处理. package main //error处理方式演示 //author: Xiong Chuan Liang //date: 2015-2-26 import "fmt" import "errors" func main() { errType(test0()) errType(test1(" test1 ")) errType(tes

C语言错误解析---关于结构体问题

问题描述:error C2224: left of '.err' must have struct/union type 分三块来讲述: 1 首先://注意在C和C++里不同 在C中定义一个结构体类型要用typedef: typedef struct Student { int a; }Stu; 于是在声明变量的时候就可:Stu stu1;(如果没有typedef就必须用struct Student stu1;来声明) 这里的Stu实际上就是struct Student的别名.Stu==stru

43&gt;&gt;c语言错误信息

1. warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration] warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default] (矛盾的 含蓄的) reason: 使用malloc时没有包含库stdlib.h method: 添加库咯 2. undefined r