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

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

    关注

    90

    文章

    3707

    浏览量

    96765
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73150

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    单片机开发功能安全中编译器

    在各个领域,功能安全领域对开发人员提出了新要求。功能上安全的代码必须包括防御性代码,以防御各种原因引起的意外事件。例如,由于编码错误或宇宙射线事件而导致的内存损坏可能导致执行根据
    发表于 12-01 06:44

    家门口的科技盛宴!给你三个不得不去CEIC 2025的理由!

    行业资讯
    脑极体
    发布于 :2025年11月03日 10:08:30

    Matter的工作原理和演进历程

    对消费者而言,设备互联一直颇为复杂。他们不得不在生态系统中艰难抉择(每个生态的设备选择有限),跨生态添加设备时则面临兼容挑战,此外,还要担忧设备与家庭生态系统的安全
    的头像 发表于 09-29 16:48 873次阅读

    CE自愿证书不得出现“certification”字样及CE标志

    欧盟重申CE标志使用规范,明确自愿证书不得出现“certification”字样及CE标志,以防止消费者误解证书性质,维护CE标志权威
    的头像 发表于 09-19 11:20 629次阅读
    CE自愿<b class='flag-5'>性</b>证书<b class='flag-5'>不得</b>出现“certification”字样及CE标志

    无人机为什么能稳定飞行?IMU功不可没

    无人机在天空中自由穿梭、稳稳悬停,背后究竟是什么在发挥关键作用呢?这就不得不提到一个重要部件 ——IMU。
    的头像 发表于 08-12 14:27 1131次阅读

    SPI通信可不可以不使用中断?

    你好,我目前在使用TC377芯片,我需要在PWM中断内使用QSPI通信,出于某种原因,我不得不将PWM中断优先级提到最高,这导致我无法进入spi中断。因此,我希望知道SPI通信可不可以不使用中断?
    发表于 07-31 08:15

    智同科技推动国产RV减速器行业发展

    把时间拨回十年前,我们不得不承认,国产RV减速器行业在中国市场举步维艰。
    的头像 发表于 06-26 16:27 829次阅读

    芯资讯|WTK6900P语音识别芯片,引领健康个护产品迈⼊“零按键”智能交互时代

    ⼩伙伴们,不知道你们有没有⽤过眼部按摩仪或者肩颈按摩仪?有没有过这样的“尴尬”体验:当你悠哉游哉地躺在躺椅上,戴上眼部按摩仪,按得正舒服时想调节⼀下模式,却不得不中断放松状态⼿动调节按摩参数,复杂
    的头像 发表于 06-10 10:17 421次阅读
    芯资讯|WTK6900P语音识别芯片,引领健康个护产品迈⼊“零按键”智能交互时代

    唯创WTK6900P,引领按摩器等健康个护产品迈入“零按键”智能语音交互时代

    小伙伴们,不知道你们有没有用过眼部按摩仪或者肩颈按摩仪?有没有过这样的“尴尬”体验:当你悠哉游哉地躺在躺椅上,戴上眼部按摩仪,按得正舒服时想调节一下模式,却不得不中断放松状态手动调节按摩参数,复杂
    的头像 发表于 05-27 12:03 423次阅读
    唯创WTK6900P,引领按摩器等健康个护产品迈入“零按键”智能语音交互时代

    关于渗压计的这些问题不得不知……

    行业资讯
    南京峟思工程仪器
    发布于 :2025年03月20日 17:30:21

    不得不知的PCB丝印类型及其重要作用!

    一站式PCBA智造厂家今天为大家讲讲pcb丝印的类型及其作用有哪些?PCB丝印的类型及其作用。在现代电子制造领域,PCB的设计和生产过程中,丝印是一个不可忽视的重要环节。丝印不仅能提升PCB的可读
    的头像 发表于 03-17 09:48 1296次阅读

    从初级到高级:工业自动化编程岗位的真实写照

    在工业自动化领域,存在着一种看似普遍的现象:不到 30 人的小型自动化集成公司,工程师们使用着国产低价的 PLC 替代品,却仍觉得成本压力巨大,甚至为了节省开支,不得不退而求其次,选用一些老旧
    的头像 发表于 03-05 10:08 797次阅读
    从初级到高级:工业自动化<b class='flag-5'>编程</b>岗位的真实写照

    【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用

    前言大家有没有遇到过这样的问题:明明已经启用了某个功能,却因为编译报错不得不进入menuconfig去启用其依赖的功能;或者是为了启用某个功能,需要在menuconfig中四处寻找相关选项,甚至有
    的头像 发表于 02-20 19:57 583次阅读
    【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用

    中兴通讯40年——五个不得不说的故事

    今年2月7日是中兴成立40年。 我写了《华为通信科技史话》的书(人民邮电出版社),从侧面体现了同城兄弟中兴通讯的科技发展过程。 中兴历史上有五个重要的故事。 1、中兴在1993年凤凰涅槃 1985年2月7日,由侯为贵先生牵头,航天科技771所(当时是691厂)等单位共同出资成立了中外合资企业——深圳市中兴半导体有限公司。 1993年4月,中兴半导体公司改组,691厂、深圳广宇工业公司与民营科技企业深圳中兴维先通公司共同投资组建深圳市中兴新通讯设
    的头像 发表于 02-13 16:04 5145次阅读
    中兴通讯40年——五个<b class='flag-5'>不得不</b>说的故事

    gitee 支持的编程语言有哪些

    Gitee 支持的常见编程语言: Python :一种广泛使用的高级编程语言,以其清晰的语法和代码可读而闻名。 Java :一种面向对象的编程
    的头像 发表于 01-06 09:50 1108次阅读