0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

代码防御性编程不得不知的技巧

Q4MP_gh_c472c21 来源:C语言与CPP编程 作者:自成一派123 2021-11-22 09:49 次阅读

1 什么是防御性编程?顾名思义,防御性编程是一种细致、谨慎的编程方法。为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能的”保护”自己。我们通过明确地在代码中对设想进行检查,这是一种努力,防止我们的代码以将会展现错误行为的方式被调用。

防御性编程使我们可以尽早的发现较小的问题,而不是等到它们发展成大的灾难的时候才发现。其开发软件的过程是:

下面总结了一些防御性编程的反对和支持者的意见:

反对者:

它降低了代码的效;即使是一个很小的额外代码也需要一些额外的执行时间。它对于一个函数来说也许不要紧,但是对于一个由10万个函数组成的系统,问题就变得严重了。

每种防御性的做法都需要一些额外的工作;

支持者:

防御性编程可以节省大量的调试时间,使你可以去做更有意义的事情。

编写可以正常运行、只是速度有些慢的代码,要远远好过大多数时间都正常运行、但是有时候会崩溃的代码。

防御性编程避免了大量的安全性问题。

防御性编程技巧使用好的编码风格和合理的设计

采用良好的编码风格,来防范大多数编码错误。如:

const关键字:

关键字const可以给读你代码的人传达非常有用的信息。例如,在函数的形参前添加const关键字意味着这个参数在函数体内不会被修改,属于输入参数。

同时,合理地使用关键字const可以使编译器很自然的保护那些不希望被修改的参数,防止其被无意的代码修改,减少bug的出现。

volatile关键字:

在一些并行设备的硬件寄存器(如状态寄存器),中断服务子程序中会访问到的全局变量以及多线程应用中被几个任务共享的变量前使用volatile关键字来防止编译优化。

static关键字:

函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。

在模块内的static全局变量可以被模块内的所有函数访问,但不能被模块外其它函数访问。

在模块内的static函数只可能被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内。

位操作运算中,尽可能使用《《、 》》、 &、|等运算符,尽可能少使用/、%、*运算符。

变量和函数的命名要有意义,并且尽可能做到一个函数只做一件事情。

多采用面向对象的思想来编写代码。

在投入到编码工作之前,先考虑大体的设计方案,这也非常关键。

不要仓促的编写代码

欲速则不达,每敲一个字,都要想清楚你要输入的是什么。在写每一行时都三思而后行。可能会出现什么样的错误?你是否已经考虑了所有可能出现的逻辑分支?放慢速度,有条不紊的编程虽然看上去很平凡,但这的确是减少缺陷的好办法。

C语言编程中,追求速度的程序员经常会出现的一个问题就是将”==”错误的输入为”=”,而有些编译器并不会警告,这就会造成问题。

不要相信任何人

这里是指用怀疑的眼光来审视所有的输入和所有的结果,直到你能证明这段代码是正确的时候为止。

编码的目标要清晰,而不是简洁

简单是一种美,不要让你的代码过于复杂。即编写的代码一定要逻辑清晰,可读性强。

编译时打开所有警告开关

在你的代码中产生任何警告信息,都应立即修正代码。要知道警告的出现总是有原因的。即使你认为某个警告无关紧要,也不要置之不理。

使用安全的数据结构

我们最常见的一些安全隐患大概是由缓冲溢出引起的。缓冲溢出是由于不正确的使用固定大小的数据结构而造成的。例如,如下这个代码:

char * unsafe_copy(const char * source)

{

char *buffer = new char[10];

strcpy(buffer,source);

return buffer;

}

如果source中的数据长度超过10个字符,它就会造成其它问题。我们可以改成如下形式:

char * safe_copy(const char * source)

{

char *buffer = new char[10];

strncpy(buffer,source,10); //用strncpy代替strcpy可以保护这个代码段

return buffer;

}

检查所有的返回值

如果一个函数返回一个值,他这样做肯定是有理由的。检查这个返回值,如果返回值是一个错误代码,你就必须辨别这个代码并处理所有的错误。不要让错误悄无声息的侵入你的程序;大多数难以察觉的错误都是因为程序员没有检查返回值而出现的。

审慎的处理内存

对于在执行期间所获取的任何资源,必须彻底释放。

在声明位置初始化所有变量

如果你意外的使用了一个没有初始化的变量,那么你的程序在每次运行的时候都将得到不同的结果,这取决于当时内存中的垃圾信息是什么。这样会造成很多随机的行为,给查找带来很多的麻烦。因此,需要在声明每个变量的时候就对它进行初始化。

同时,平时编码时还要注意一些细则

提供默认的行为:Switch语句中将default case的执行明示出来。同样地,如果你要编写一些不带else子句的if语句,停下来想一想,你是否该处理这个逻辑上的默认情况

检查数值的上下限:确保每次运算数值变量都不会溢出,即数据类型的使用要谨慎

注意强制转换是否合理

声明变量,可以使变量的声明位置与使用它的位置尽量接近,从而防止它干扰代码的其他部分

加合理的异常处理、日志文件

正确设置常量

优秀的程序应该做到:关心代码是否健壮

确保每个设想都显示地体现在防御性代码中

希望代码对无用信息的输入有正确的行为

在编程的时候认真思考自己所编写的代码

编写可以保护自己不受其他人的愚蠢伤害的代码。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3587

    浏览量

    93580
  • 代码
    +关注

    关注

    30

    文章

    4741

    浏览量

    68324

原文标题:代码防御性编程的10条技巧

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【解决方案】提升新能源汽车续航能力,你不得不知晓的测量知识

    前言对于以新能源车为代表的电动出行(E-Mobility)来说,续航里程的提高是最重要的课题之一。为了实现这一点,除了要掌握电池和大功率的动力传动系统的状态外,还要掌握ECU和电装设备等零部件的功耗和暗电流。何为汽车暗电流?暗电流(darkcurrent),指点火开关在OFF的位置(汽车无工作的状态,也可以指静止休眠状态)时,仍然在流动的电流,又可称为“静态
    的头像 发表于 09-05 11:22 225次阅读
    【解决方案】提升新能源汽车续航能力,你<b class='flag-5'>不得不知</b>晓的测量知识

    不得不知的pcba加工规则:确保元器件安全可靠

    一站式PCBA智造厂家今天为大家讲讲PCBA加工如何确保质量和性能的稳定性?PCBA加工规则。在PCBA加工生产过程中,严格遵守操作规则至关重要,以确保元器件的安全和可靠。以下是几个基础而重要
    的头像 发表于 08-26 09:25 230次阅读

    防御性编程:让系统坚不可摧

    1. 引言 面对复杂多变的运行环境、不可预测的用户输入以及潜在的编程错误,如何确保软件在遭遇异常情况时依然能够稳定运行,是每位开发者必须面对的挑战。防御性编程(Defensive
    的头像 发表于 07-25 14:04 239次阅读

    拒绝渗漏,安全、快速、有效的治理变压器渗漏油

    电厂变压器渗漏油,用这种技术治理立竿见影,不得不称赞!
    的头像 发表于 07-25 10:45 250次阅读
    拒绝渗漏,安全、快速、有效的治理变压器渗漏油

    精密空调—不得不服的精密空调"黑科技"!逆天了#精密空调

    精密空调
    北京汇智天源
    发布于 :2024年07月20日 12:33:01

    不得不爱的保护装置-安全就这么简单

    保护装置
    jf_18500570
    发布于 :2024年07月01日 10:20:02

    用aurix development studio调试代码时,导致调试中断的原因?

    当我用 aurix development studio 调试代码时,总是出现严重错误,导致调试中断,我不得不重启 studio,然后重新开始调试。 当我点击进入某些代码行时,错误总是发生,这些
    发表于 06-03 08:11

    工科人关于T3Ster热阻测试仪不得不知道的九大特点

    T3Ster是一款先进的半导体器件封装热特性测试仪器,在数分钟内提供各类封装的热特性数据。T3Ster专为半导体、电子应用和LED行业以及研发实验室的应用而设计。系统包括易用的软件部分和硬件部分,T3Ster用来测量封装半导体器件以及其他电子设备的瞬态热特性,测量的器件包括分离或集成的双极型晶体管、MOS晶体管、常见的三极管、LED封装和半导体闸流管,各种封装类型的器件和微机电系统的一些部件。因其配备的专业的设备和软件,它也能测试PWB、
    的头像 发表于 04-25 09:12 636次阅读
    工科人关于T3Ster热阻测试仪<b class='flag-5'>不得不知</b>道的九大特点

    关于MCU选型不得不知的学问

    MCU选得好不好,往往决定着产品和商业OK不OK。 这个质量,可能是芯片抗干扰强不强?能不能过产品认证? 也可能是在某一温度能否稳定运行? 还有可能是有些应用外设有没有坑?
    的头像 发表于 04-15 10:16 401次阅读

    计算机最核心的——CPU

    在CPU的四个结构中,寄存器的重要远远高于其余三个,为什么这么说?因为程序通常是把寄存器作为对象来进行描述的。而说到寄存器,就不得不说到汇编语言,说到汇编语言,就不得不说到高级语言,说起高级语言也就
    发表于 03-13 14:04 1679次阅读
    计算机最核心的——CPU

    一不小心就炸机!你不得不知道的,示波器测试的共地问题

    大家都知道示波器的检测探头测到哪里,哪里就和示波器共地。两个不共地的检测点,一旦被同一个示波器检测时,它们就会自动共地。多通道测试时,一定要注意这个问题。 1.测试两组共地信号 如下示意图: 输入1V的小信号,经过信号的处理放大,输出100V的大信号。 想知道输出波形是否失真,有时候肉眼不一定能够看出来。这时候需要测试输入波形,再跟输出波形进行对比。因为输入输出信号都是共地的,所以可以用一般的无源单端探头进行测试,如
    的头像 发表于 02-27 10:06 1496次阅读
    一不小心就炸机!你<b class='flag-5'>不得不知</b>道的,示波器测试的共地问题

    GD32固件库里时钟配置时的神秘代码?高频切低频时芯片会发生什么

    在GD固件库的时钟配置函数里看到这样一段神秘代码,研究分析后不得不佩服原厂固件库里的细节处理
    的头像 发表于 02-19 09:44 629次阅读
    GD32固件库里时钟配置时的神秘<b class='flag-5'>代码</b>?高频切低频时芯片会发生什么

    一种动态防御策略——移动目标防御(MTD)

    网络攻击的技术变得愈发难测,网络攻击者用多态、混淆、加密和自我修改乔装他们的恶意软件,以此逃避防御性的检测,于是移动目标防御(MTD)技术出现了,通过动态地改变攻击面,有效地对抗日益复杂和隐蔽
    的头像 发表于 01-04 08:04 1430次阅读
    一种动态<b class='flag-5'>防御</b>策略——移动目标<b class='flag-5'>防御</b>(MTD)

    PCB设计工程师不得不知的法则

    PCB是进行设计的物理平台,也是用于原始组件进行电子系统设计的灵活部件。本文将介绍几种PCB设计黄金法则,这些法则自25年前商用PCB设计诞生以来,大多没有任何改变,且广泛适用于各种PCB设计项目
    发表于 12-20 15:57 177次阅读

    Morphisec革命:利用移动目标防御增强Windows安全

    Windows10安全工具阵列仍然存在明显的防御漏洞,Morphisec通过其革命的自动移动目标防御(AutomatedMovingTargetDefense)技术,强化Windows10安全
    的头像 发表于 12-09 10:00 1028次阅读
    Morphisec革命:利用移动目标<b class='flag-5'>防御</b>增强Windows安全<b class='flag-5'>性</b>