MISRA中文网站 > 使用教程 > MISRA C 2023和MISRA C 2012差别大吗 MISRA规则版本升级会影响哪些既有代码
教程中心分类
MISRA C 2023和MISRA C 2012差别大吗 MISRA规则版本升级会影响哪些既有代码
发布时间:2026/06/29 17:12:47

  MISRA C 2023和MISRA C 2012差别大吗MISRA规则版本升级会影响哪些既有代码,这事不能简单用“大”或“不大”来回答。如果一个项目以前只按最早的那版MISRA C:2012做检查,后面那些修正案和技术勘误从来都没跟过,那升到MISRA C:2023后的差异就会比较明显;可要是项目一直坚持按MISRA C:2012加上各类修订文件来执行,那么MISRA C:2023对它来说,倒更像是一次合并整理,把之前散在各处的修订内容都放进了一个新的版本基线里头。

  一、MISRA C 2023和MISRA C 2012差别大吗

 

  MISRA C:2023带来的变动,并不是那种把原先规则全都推翻再重来的类型,它底下那些基本的想法一直都没被改掉,还是靠限制C语言里那些容易写错、不好验证、行为不定的写法,来把代码的安全性、可靠程度和可维护程度往上提一提。真正在变的地方,主要是规则被重新理了一遍,语言标准的覆盖范围变宽了,几次修订里的内容被正式合并了进来,还有一部分规则的说法讲得比过去更清楚了一些。

 

  1、底下的想法没有变

 

  MISRA C:2012和MISRA C:2023,说到底是全都在管C语言天生的那些风险,像隐式类型转换、针指的使用、数组的越界、没给明确定义过的行为、怎么也跑不到的死代码,还有表达式里夹带进来的副作用,这些东西照样都是检查时不会松劲的地方。对于那些一直在老老实实照着MISRA C:2012做下来的项目来说,并不会因为换成了2023版,从前那套设计办法和写码子的习惯就全都一下子作废了,多数时候规则只是被讲得更明白了,方向并没有被拧到反的那一面去。

 

  2、用起来版本基线更集中

 

  MISRA C:2023这个新版本把本来散在好几个修订文件里头的内容,全给收进了同一个版本里,MathWorks在介绍MISRA C:2023时也说过,它把从Amendment 1到Amendment 4里头新加的和改过的规则,都给整到了一块儿。这么一来,对团队平常的管理反而是省了些事,以后也就不用再为“是该照着2012原版来,还是该照着2012加上某个Amendment”这号事情扯个没完。

 

  3、对新一点的语言特性会更敏感

 

  相当多的老项目写到现在还是C90或C99那套路子,要是这么个情况,那往MISRA C:2023迁移时感觉到的差别并不会有多大;可是如果项目已经开始用上了C11或C18才带来的那些特性,特别是牵涉到多线程、原子操作、并发访问这些东西,那带来的影响就会变得挺显眼的。Embedded.com在解读MISRA C:2023时就讲过,MISRA C:2012的Amendment 4本来就是专门对付C11和C18新带进来的并发特性的,而2023版把这些内容全给并了进来,所以只要代码里碰了并发这块,检查的严格劲儿肯定是比以前要紧的。

 

  二、MISRA规则版本升级会影响哪些既有代码

 

  碰上这种规则版本往上升的时候,代码受到的影响很少是一下子全部文件都大面积往外报错,更多的情况是某几类已经待了很久的老写法,忽然之间就被更细的规则、更严的工具设定,或者是不太一样的理解角度给揪了出来。项目越老,不同时期攒下来的代码风格就越杂,这种影响也就越容易凑在一批文件里同时往外冒,刚开始跑扫描那阵子,常常给人一种告警数量忽然涨起来不少的感觉,可那里头其实好一些是早该被揪出来的老毛病。

 

  1、以前留下来的那些老代码

 

  在一些年头比较长的旧代码里,能瞧见的强制类型转换、没给起名字的魔法数字、套了好几层的复杂宏、随处可以被碰到的全局变量、没被保护起来的共享状态、拿地址偏移去操作的指针,还有有符号数和无符号数不加处理就搅在一块儿算,这些东西在升级到新的规则基线以后,都很有可能多带出来一堆告警。特别是那些当年为了赶把子进度,抱着“先能跑起来再说”的心思写下的代码,一旦被摆到新规则跟前,很容易就又被重新扫出来了,而且常常是才动了一处,就扯出身旁一长串有关联的麻烦。

  2、并发和共享数据那块的代码

 

  只要是牵涉到了任务、线程、中断服务程序、共享缓冲区,还有用来在模块中间传信的全局状态标志,这些部分的代码都应该被重点拿出来再重新过一下眼。早些时候有不少项目,实际上是靠着开发人员个人的经验和小心去绕开冲突的,至于数据竞争要怎么去防、锁拿取的先后次序该怎么样定,还有临界区那条界线到底应该圈多长,这些地方并没有被写得特别明白。规则版本一旦升上去,这类隐患倒不一定会立刻就炸成运行中的功能bug,可到了做静态扫描或者代码评审的时候,几乎是肯定要被揪出来追着问的,再加上并发问题本来就不太好复现,解释起来就更费劲了。

 

  3、工具自动扫描出来的那批结果

 

  升级之后头一个变了模样的,十有八九还不是代码本身,而是开发环境里面那套用来扫代码的静态分析工具的规则包,原本一直都能顺顺当当通过检查的那些文件,在给换上了MISRA C:2023规则集之后,很可能会又多冒出来一些之前没见过的告警条目,再不然就是原来那些告警的分类等级被悄悄给调过了。碰到这种时候,千万别一看到告警数目比过去多了就急急去改代码,应该先去确认一下工具的版本对路不、旧规则和新规则之间的映射关系是不是都理清了、编译时用的选项有没有变动,还有以前特意被标成排除的那些项现在还能不能对得上。

 

  三、怎么处理能更稳当一些

 

  给MISRA版本做升级,是不大建议一上来就把整个项目一把头全切过去,然后催着管开发的几个人在很短的时日里把冒出来的所有问题一口气都给清干净,比较挨着地面的搞法,还是先花点力气把新旧两套规则中间的那些差别给评估清爽,然后再分成几拨、有个先后地去处置那些风险明显偏高的模块。特别是对那些已经维护了好些年的老项目,控制步子就显得更要紧了,可不能单单为了追那个新版本的合规,反倒把本来一直跑得稳稳妥妥的代码给改出了新的毛病。

 

  1、先要把规则差异和工具基线给确认下来

 

  可以围绕【MISRA C:2012规则集】和【MISRA C:2023规则集】做一次对比扫描,先看新增告警集中在哪些模块、哪些规则类型、哪些历史写法上。

 

  在这个阶段先别急着去碰代码,把刚才扫出来的那一批告警好好给它们归一归类:哪些是真的毛病,哪些是工具配置没调对才误报出来的,哪些是以前反反复复讨论过认为可以被接受的偏离,还有哪些是得重新拉出来让技术负责的人去评审再定一定性的,等把这些分门别类的活计都做完了,后面再去一项一项动手时才不会乱掉阵脚。

 

  2、把高风险的代码放在前头去处理

 

  和安全性牵得比较紧的模块、贴近硬件那一层的底层驱动、负责通信的协议栈、用来做故障诊断的那一部分,还有动不动就要频繁去读写内存的代码,这些都应该被排在前头先过一遍,普通格式上的那些小毛病可以先往后面放一放;但是像针指的操作、并发的控制、没给定义过的行为、数据到底有没有效的那一类检查,就得早一点动手去解决,在着手改代码以前,最好是能先把对应的回归测试给补一补或者补齐全了,千万别为了追规则的合规,却把原来功能上的正确性给弄丢了。

 

  3、把项目自己的那些规范一块儿更新了

 

  光是把自动扫描工具那套规则集给换掉,远不算是整个版本升级就做完了,项目内部自己定下的编码规范、做代码评审时对着看的检查清单、偏差申请和审批的那一整趟流程、挂在持续集成里头的检查策略,还有丢给外面的供应商去交货的验收要求,这些零碎但又很要命的东西全都得跟着一起往前走。

  总结

 

  MISRA C 2023和MISRA C 2012差别大不大,还有MISRA规则版本升级会影响哪些既有代码,根子上要看项目原来照着做到了什么份上,单拿原版MISRA C:2012查过的项目,升级后就会觉得差别比较显眼;而那些一路跟过好多个Amendment和勘误的项目,挪过去的压力相对就要小不少。

135 2431 0251