【代码大全】笔记-“防御式编程”

本文深入探讨防御式编程的核心理念,旨在确保程序即使在面对非法输入数据时也能保持稳健。文章详细介绍了防御策略,包括检查外部数据、参数验证、错误处理及断言使用,强调了在开发和维护阶段合理应用防御性代码的重要性。

防御式编程

  • 防御式编程的主要思想是:子程序应该不因传入错误的数据而被破坏,哪怕是由其他子程序产生的错误数据。更一般的说,
  • 其核心思想是要承认程序都会有问题,都需要修改,聪明的程序员应该根据这一点来编程。
  • 防御式编程是针对程序外部的保护

保护程序免遭非法输入数据的破坏

通常有三种方法来处理非法数据

  • 检查所有来源的于外部数据的值
    外部数据来源于文件,用户输入,网络或其他外部接口,应检查这些值是否在合法的范围之内。
  • 检查子程序所有输入参数的值
    子程序的参数可能是错误的,需要检查。例如
void get_process_type( uint8_t num)
{
	if((0 <= num ) && (num < MAX_NUM)) {
		......
	}
	
	.....
}
  • 决定如何出入错误的输入数据
    一旦监测到非法的参数,你该如何处理它?根据情况而定。

断言

  • 断言实在开发期间使用的、让程序在运行时自检的代码
  • 断言为真,则说明程序运行正常,断言为假,则说明程序发生错误。如
  RT_ASSERT(dev != RT_NULL);
  • 断言对于大型负责程序或可靠性要求极高的程序而言非常有效,程序员可以通过断言快速定位程序中的关键错误。

断言可以检查的错误

  • 输入参数或输出参数取值处于预期范围内
  • 指针非空
  • 传入子程序的数组或其他容器至少能容纳X个数据元素
  • 仅用于输入的变量的值没有被子程序所修改
  • 文件或流已用只读,只写或读写的方式打开

什么时候使用断言

  • 主要用于开发和维护阶段
  • 只在开发阶段被编译到目标代码中,而在生成产品代码时不编译到产品代码中。

断言和错误处理的使用状况

  • 断言用来检查永远不应该发生的状况,用于检查代码中的bug,因此断言通常采用强制强制退出程序的方式。
  • 错误处理,用来检查程序的程序的非正常状况,这些情况能在写代码时就预料到,比如从文件读取的汽车速度数据,应该在0-300Km/h范围内,超出了这个范围内被认为是数据出错。

错误处理技术

错误处理技术(Error-Handing-Techniques)用于处理那些能够预测的数据出错,常见的处理方法包括

  • 返回中立值
    处理错误数据最佳做法就是继续执行操作并简单地返回一个没有危害的数值。
    比如,数值计算可以返回0、字符串操作可以返回空字符串,指针操作可以返回一个空指针。
  • 换用下一个正确的数据(实时系统)
  • 返回与前次相同的数据(数据处理)
  • 换用最接近的合法数据(预先设置)
    在这里插入图片描述

其他错误处理技术

  • 错误信息记录到日志文件中
  • 返回一个错误码
  • 调用集中的错误处理子程序或对象
  • 当错误发生时显示出错消息
  • 最稳当的方式是在局部处理错误
  • 关闭程序

辅助调试的代码

使用内置的预处理

对于辅助调试代码,并非在发布产品中做实质性的移出,而是采用条件编译的方式再最终程序中不生成这些代码。

  • 要想编译时包含调试用的代码,使用#define 来定义DEBUG符号

  • 要想将其排除在外,则不要定义DEBUG符号

    #define DEBUG
    
    #ifdef DEBUG
    	//debug code 
    #endif
    

使用调试存根

存根是一段代替有效程序的简单程序
开发存根:开发阶段检查指针的子程序

void check_pointer(void *p)
{
	//执行第1项检查:可能是检查它不为NULL
	//执行第2项检查:可能是检查它的地址是合法的
	//执行第3项检查:可能是检查它所指向的数据完好无损
	...
	//执行第n项检查:
	
}

产品存根:产品阶段检查指针的子程序
void check_pointer(void *p)
{
	//No code;just return to caller 
}

确定在产品代码中该保留多少防御式代码

防御式编程存在这么一种矛盾的观念
在产品开发阶段,希望现实出的错误越多越好,引入很多防御性的代码
在产品发布阶段,希望错误尽可能不要在使用中出现

保留防御性代码的建议

  • 保留那些检查重要错误的代码
  • 去掉检查细微错误的代码
  • 去掉可以导致程序硬件奔溃的代码
  • 保留可以让程序稳妥奔溃的代码
  • 为你的技术人员记录错误信息
  • 确认留在代码中的错误消息是友好的

对防御式编程采取防御的姿态

  • 过度的防御式编程也会引入问题
  • 如果在程序的每一个想到的地方都进行参数检查,错误保护等,那么程序将会变的臃肿而缓慢,更槽糕的是,防御式编程引入的额外代码增加了软件的复杂度,反而容易造成错误。
  • 因此,只在适当的地方使用防御式编程

总结

  • 防御式编程是指无论程序存在的外部条件如何,都要保证程序的正确性
  • 防御式编程技术 :断言、错误处理技术
  • 在做防御式编程的同时需要考虑如何有步骤的取消发布软件中的部分防御式编程代码。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值