MISRA中文网站 > 最新资讯 > MISRA C指针运算有哪些限制 MISRA C指针运算违规怎么检查
教程中心分类
MISRA C指针运算有哪些限制 MISRA C指针运算违规怎么检查
发布时间:2026/08/18 16:27:36

  在嵌入式C代码中,指针加减、数组遍历和缓冲区访问非常常见,但这类写法一旦越过有效对象边界,就可能造成未定义行为或访问错误。MISRA C因此没有把重点放在“能不能使用指针”,而是要求指针运算的目标范围、两个指针之间的关系以及访问边界都能够被明确判断。处理“MISRA C指针运算有哪些限制,MISRA C指针运算违规怎么检查”时,重点应关注Rule 18.1至Rule 18.4,并结合静态分析和代码审查确认指针始终处于合法对象范围。MISRA官方对Rule 18.1的补充说明也进一步明确了指针运算与对象边界之间的关系。

  一、MISRA C对指针运算有哪些限制

 

  指针运算相关规则主要围绕一个原则展开:指针不能因为地址计算而脱离原本所属的数组或对象。即使计算出的地址在硬件上仍属于有效RAM,也不能因此认为代码满足MISRA要求。

 

  1、指针计算不能超出原数组

 

  Rule 18.1要求,由指针运算得到的结果仍应属于原来的数组对象范围。单个普通对象在这一规则下,也需要按照单元素数组的思路理解。MISRA官方技术勘误还专门补充了对象转换成字符指针后的边界处理方式。

 

  例如:

  实际检查时,不应只看当前表达式,而要继续跟踪该指针后面有没有被解引用。

 

  ①确认指针最初指向哪个【数组或对象】。

 

  ②计算每次偏移后可能达到的【最小下标】和【最大下标】。

 

  ③循环中使用变量偏移时,重点检查【循环上限】。

 

  ④如果静态分析无法证明偏移范围安全,应进一步补充边界约束,而不是直接忽略告警。

 

  2、两个指针相减必须有明确对象关系

 

  两个指针之间做减法通常用于计算数组元素间距,但这种操作需要建立在它们属于同一个数组对象的前提下。MISRA针对指针相减和数组边界分别设置限制,也是为了避免两个无关地址参与运算。MISRA官方关于指针规则的修订材料将Rule 18.1、18.2和18.3作为同一组相关约束处理。

 

  不建议出现这种写法:

  虽然两个变量可能恰好位于相邻内存区域,但它们属于不同数组,不能依赖实际地址布局解释结果。

 

  3、尽量避免直接使用指针加减表达式

 

  Rule 18.4专门针对指针参与加减运算的形式进行限制,其目的之一是提高代码可读性,让数组访问范围更容易审查。MISRA官方论坛也明确指出,类似指针加法表达式属于Rule 18.4关注范围。

 

  例如原代码为:

  在语义允许的情况下,可改成更容易检查的数组形式:

  ①普通缓冲区访问优先使用【数组下标】表达。

 

  ②遍历固定数组时,让【下标变量】体现当前位置。

 

  ③确实需要移动指针时,要单独证明移动范围不会超出对象边界。

 

  ④不要为了消除Rule 18.4告警,把指针转换成整数后再做地址运算,这还可能引入其他指针转换规则问题。MISRA官方论坛给出的示例中,指针加法后再转换成整数同时涉及Rule 18.4和Rule 11.4。

 

  二、MISRA C指针运算违规怎么检查

 

  静态分析工具发现指针运算问题后,不建议只根据某一行表达式判断。很多违规来自循环边界、函数参数长度或跨函数传递,必须结合完整数据范围检查。

  1、先定位是哪一种指针运算

 

  ①搜索【指针+整数】和【指针-整数】表达式。

 

  ②检查【+=】和【-=】是否直接用于指针。

 

  ③查找两个指针之间的减法。

 

  ④检查指针是否用于大小关系比较,以及参与比较的指针是否来自同一对象。

 

  ⑤对数组下标继续检查实际范围,因为改写成数组形式并不会自动消除越界风险。

 

  例如:

  这种写法虽然避免了直接的指针加法,但仍需要证明【len】不会超过调用者实际提供的缓冲区长度。

 

  2、重点检查循环和函数参数

 

  ①查看循环终止条件是否可能让指针多移动一次。

 

  ②参数同时存在【指针】和【长度】时,检查两者是否始终匹配。

 

  ③指针经过多个函数传递时,从最初对象开始追踪实际容量。

 

  ④对DMA缓冲区、通信报文和寄存器映射等特殊场景,不能因为地址固定就直接关闭规则。

 

  ⑤静态工具给出“范围无法确定”时,应补充调用约束、数组长度或接口设计,让分析器能够证明访问范围。

 

  三、现有指针运算代码怎么整改

 

  已经存在大量指针运算时,整改重点不是把所有指针全部换成数组,而是让对象边界、偏移范围和访问条件更加明确。这样既便于静态分析工具判断,也更方便代码评审。

 

  1、优先把直接指针运算改成数组访问

 

  ①对连续缓冲区遍历,优先把【指针加减】改成【数组下标】。

 

  ②原来使用“指针+偏移量”访问元素时,可以在语义一致的情况下改成对应的数组形式。

 

  ③循环中的下标上限应来自【实际数组长度】,不要使用无法说明来源的固定数字。

 

  ④修改后重新检查循环结束条件,确认最后一次访问没有超过有效元素范围。

 

  例如:

  可以在条件允许时调整为:

  这样的写法更容易直接判断index是否处于有效范围内。

 

  2、指针参数同时传递长度

 

  函数只接收一个裸指针时,函数内部通常无法知道目标对象到底有多大,这也是静态分析经常无法证明访问安全的原因。

 

  ①接口包含缓冲区指针时,同时传入【元素数量】或【缓冲区长度】。

 

  ②进入函数后先检查长度,再进行数组访问。

 

  ③多层函数调用时,继续向下传递长度信息,不要中途只保留指针。

 

  ④如果某个函数只允许处理固定大小数组,可以直接明确【最大长度】,减少不确定范围。

 

  这样做可以让“指针指向哪里”和“最多能访问多少数据”同时保持可追踪。

 

  3、确实需要保留指针运算时单独论证

 

  底层驱动、硬件寄存器或特定内存管理代码中,有些指针运算很难完全消除。这类代码不能简单关闭静态分析告警。

 

  ①明确指针所属的【对象或数组】。

 

  ②计算可能出现的【最大偏移量】和【最小偏移量】。

 

  ③检查所有分支和循环是否都能保证偏移处于有效范围。

 

  ④无法按照规则直接整改时,再根据项目的MISRA合规流程准备正式偏离说明。

 

  偏离记录应能够说明为什么必须保留这种实现、访问范围怎样受控,以及通过哪些测试或分析证明不存在越界风险。

  总结

 

  MISRA C对指针运算进行限制,主要是为了让内存访问范围更加确定,减少越界、无关对象地址运算以及难以分析的访问行为。实际项目中,判断是否合规不能只盯着某一个指针表达式,还要结合指针来源、对象范围和调用关系一起分析。对遗留代码进行整改时,重点应放在提高边界可证明性和接口可追踪性上。如需进一步了解MISRA C指针运算限制、边界违规检查与代码整改,欢迎联系咨询。

135 2431 0251