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

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

3天内不再提示

静态分析有助于代码可移植性

星星科技指导员 来源:嵌入式计算设计 作者:Chris Tapp 2022-06-28 11:56 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

代码重用通常是新项目中的主要考虑因素,无论是在利用先前项目的遗留代码方面,还是作为后续项目的基础。静态分析可用于确保遗留代码不会成为项目中问题的根源,并保证在其开发过程中生成的任何代码不会影响任何将其作为代码库的项目。

C 代码特别容易受到移植问题的影响,特别是因为不能期望编译器检测到它们,因为代码将符合语言规范(假设没有使用语言扩展)。因此,开发人员必须使用静态分析工具来确认移植将按计划进行。静态分析工具可以通过多种方式帮助解决此问题。

int 大小引起的可移植性问题

int 中的精度(位数)可能因系统而异。为了解决这个问题,通常定义一组 typedef 来将系统类型映射到应用程序类型。可以为 16 位架构定义以下示例:

typedef 无符号字符 U8;

typedef unsigned int U16;

typedef unsigned long U32;

如果将代码移植到 32 位架构,则此示例可以更改为以下内容:

typedef 无符号字符 U8;

typedef 无符号短 U16;

typedef unsigned int U32;

然而,移植并不是那么简单,因为 int 大小的变化会对代码产生一些不太明显的影响。例如,其结果取决于整数提升效果的任何表达式都可能表现出不同的行为。因此,只有在包含受影响类型的对象的所有表达式中的精度符合目的时,这种更改才合适。静态分析可以用来验证这个假设。

编译器不会报告任何这些问题,因为代码对于目标环境完全有效,即使它的行为可能不符合预期。

编译器实现引起的可移植性问题

与编译器相关的实现定义的、未指定的或未定义的行为的差异可能会导致移植时出现缺陷。

实现定义的行为是编译器之间可能不同但由编译器供应商记录的行为。静态分析工具可以检测调用此类行为的代码,以便将其消除以促进移植。

也可以检测到未指定或未定义的行为;但是,它带来的不仅仅是可移植性问题,因为这种行为可能会在同一编译器的不同版本之间以未记录的方式发生变化,甚至可能在同一编译器内的各种用例之间发生变化。调用这种行为的代码可以工作,但很可能会非常脆弱。值得注意的是,迁移到不同版本的编译器可以被视为移植。

编译器不需要检测实现定义的、未指定的或未定义的行为的使用,因为代码是完全有效的。

编码标准

诸如 MISRA C:2004 (www.misra-c.com) 等公开可用的编码标准,可以通过静态分析工具严格执行,包括防御这些可移植性问题的规则。后面的例子使用了这个标准。

C 中的整数转换

在 C 中对表达式求值期间,管理不同算术类型的隐式转换方式和时间的规则很复杂。为确保移植代码时结果符合预期,在考虑了所有此类隐式转换后,表达式中的所有操作都应以相同的类型进行。

与整数提升相关的隐式转换很容易导致代码的执行方式与开发人员期望的方式大不相同。整数提升基本上要求将任何小于 int 的类型(例如 char、short)转换为 int,然后再将其用作表达式中的操作数。许多嵌入式系统广泛使用这些类型,因为它们通常允许更有效地使用内存资源,这可能会受到限制以节省成本、空间和功率。

整数提升是保值的(意味着保留大小和符号),但对象的符号可能会改变。此外,表达式将以比操作数类型更宽的类型进行计算。考虑以下示例:

U8 u8a = 200U;

U8 u8b = 100U;

U8 u8r = u8a + u8b;

在此示例中,u8a 和 u8b 在加法发生之前都被转换为宽度至少为 16 位的有符号整数。然后将加法的结果隐式转换回 8 位,然后再存储到 u8r 中。在这种情况下,开发人员可能会期待结果 (44),因为可以合理地假设他们知道赋值时发生的模 2 运算。这意味着结果实际上与以 8 位精度进行操作时的结果相同(整数提升不影响结果)。

但是,当整数提升与隐式扩展转换同时发生时,可能会造成混淆。考虑以下:

U16 u16a = 0xffffU;

U16 u16b = 0x0001U;

U32 u32r = u16a + u16b;

在 32 位架构上,u32r 的类型为 unsigned int,而 u16a 和 u16b 的类型为 unsigned short。整数提升将导致操作数在加法之前转换为有符号整数,结果将在赋值时隐式转换为无符号整数,最终值为 0x10000。开发人员可以(也许有理由)依靠发生的整数提升来确保加法不会像使用 16 位算术时那样换行。

如果开发人员决定将代码移植到 16 位架构,则 u32r 将具有 unsigned long 类型,而 u16a 和 u16b 将具有 unsigned int 类型。这一次,在加法发生之前(也在 unsigned int 中),不会对已经是 unsigned int 的操作数应用任何转换,并且 0x0000 的结果将在赋值时隐式转换为 unsigned long,最终值为0x0000。以更广泛的类型执行添加的假设现在不再有效,并且存在发生意外回绕的风险。

这表明当代码从一个平台移植到另一个平台时,它可以多么容易地表现出不同的行为。这里的真正问题与在分配结果时发生的隐式扩大转换有关。这可以通过确保始终使用强制转换以必要的精度评估表达式来消除,例如:

u32r = (u32) u16a + u16b;

( u32 ) 强制转换确保表达式始终以具有适当精度的类型进行评估。在前面的示例中,这意味着表达式是以 unsigned long 而不是 unsigned int 计算的。如图 1 所示,静态分析可以很容易地检测到隐式加宽。

图 1: LDRA 工具套件等静态分析工具可以突出显示有效 C 代码中的问题,这些问题在移植时可能导致功能错误。因为代码是有效的 C,编译器不会检测到这些问题。

poYBAGK6fCGAQ1o2AAH-WXrqZfA267.png

整数提升也会影响其他操作。考虑以下:

u16a = 0x1234U;

u16r = ~u16a 》》 8;

在 16 位架构上,这将导致 u16a 的位被反转,顶部字节移入底部字节,将 0x00ED 分配给 u16r。

但是,在 32 位架构上,u16a 将在补码发生之前转换为带符号的 int(32 位),从而将值 0xFFED 分配给 u16r。

再一次,使用强制转换将确保行为符合预期:

u16r = ( U16 )~u16a 》》 8;

评估代码适用性

静态分析工具是代码移植的宝贵帮助。如图 2 所示,这些工具允许开发人员评估遗留代码并确保以允许移植的方式开发新代码。

图 2:静态分析工具报告,例如 LDRA 工具套件中的这个示例,可以有效评估代码移植的适用性。

pYYBAGK6fCqAaVH9AAKRnPFNo9U070.png

在项目生命周期中尽早采用静态分析将确保尽早验证遗留代码,并确保任何新代码从一开始就可移植。通过缩短开发时间和显着降低残留缺陷水平,开发人员可以快速收回使用此类工具所涉及的初始支出。

审核编辑:郭婷

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

    关注

    22

    文章

    2122

    浏览量

    76716
  • 编译器
    +关注

    关注

    1

    文章

    1670

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    大模型真的有助于自动驾驶落地吗?

    其实大模型带来的并不是单一的“万能解”,而是一个能够显著提升认知、生成和推理能力的新工具箱。它能加速数据闭环、提升对复杂场景的理解、改善人机交互、并在工程流程中提高效率。
    的头像 发表于 08-16 09:43 890次阅读
    大模型真的<b class='flag-5'>有助于</b>自动驾驶落地吗?

    汽车软件团队必看:基于静态代码分析工具Perforce QAC的ISO 26262合规实践

    ISO 26262合规指南,从ASIL分级到工具落地,手把手教你用静态代码分析(Perforce QAC)实现高效合规。
    的头像 发表于 08-07 17:33 872次阅读
    汽车软件团队必看:基于<b class='flag-5'>静态</b><b class='flag-5'>代码</b><b class='flag-5'>分析</b>工具Perforce QAC的ISO 26262合规实践

    如何在恩智浦FRDM开发平台上实现代码的高效复用

    从零开始评估微控制器可能充满挑战。即使在编写代码之前,开发人员也需要深入了解想要使用的外设的特性。它们是否能够在不同产品间以一致方式运行?这些所谓的可移植性究竟有多可靠?面对这些不确定性,创建真正可移植
    的头像 发表于 05-27 14:35 791次阅读
    如何在恩智浦FRDM开发平台上实现<b class='flag-5'>代码</b>的高效复用

    基本电路分析(经典学习指导系列)

    对于电工技术、电气工程方面的人士是个很好的借鉴,有助于电路分析。 从直流电阻电路分析开始,一直讲到交流电路。 对于数学基础方面,使用者不需要懂得微分或积分预算,用导数来说明电压与电流
    发表于 05-13 15:29

    TPS7A44 50mA、65V、低 IQ、LDO 线性稳压器数据手册

    电源),并可承受高达 85 V 的线路瞬态电压。这些特性有助于现代应用满足日益严格的能源要求,并有助于延长便携式电源解决方案的电池寿命。
    的头像 发表于 02-27 16:12 1072次阅读
    TPS7A44 50mA、65V、低 IQ、LDO 线性稳压器数据手册

    VirtualLab Fusion应用:光波导的足迹和光栅分析

    有助于确定光导及其光栅区域充分布局的特性。 今天,我们转向用于光导中光栅的最强大的系统设计工具之一:足迹和光栅分析工具。在它的许多功能中,不限于任何特定的布局,例如,它可以帮助可视化不同视场模式下
    发表于 02-11 09:45

    信号分析仪的原理和应用场景

    快速定位和解决问题,提高通信系统的可靠和效率。 无线电频谱监测: 信号分析仪可以扫描和分析无线电频谱,检测和识别不同频段的信号源。 这对于无线电频谱管理、频段规划和干扰定位非常重要,有助于
    发表于 01-17 14:37

    Code Review:提升代码质量与团队能力的利器

    降低软件中的缺陷比例;其次,它促进了知识共享,通过评审的过程,团队成员可以相互学习,增强对系统的整体理解;最后,CR是一种预防措施,它有助于维护代码的清晰和统一,减轻技术债务,提升系统的稳定性。 尽管CR有诸多好处,实际操作中却面临不少
    的头像 发表于 01-17 09:52 852次阅读

    如何提高嵌入式代码质量?

    的功能,有助于提高代码的复用和可维护。 2. 清晰的文档:包括设计文档、接口文档和代码注释,能够帮助开发人员理解
    发表于 01-15 10:48

    如何有效地开展EBSD失效分析

    失效分析的重要失效分析其核心任务是探究产品或构件在服役过程中出现的各种失效形式。这些失效形式涵盖了疲劳断裂、应力腐蚀开裂、环境应力开裂引发的脆性断裂等诸多类型。深入剖析失效机理,有助于
    的头像 发表于 01-09 11:01 946次阅读
    如何有效地开展EBSD失效<b class='flag-5'>分析</b>

    电气安规分析仪的原理和应用

    相关的安全标准和规定。这有助于企业在新产品上市前及时发现并解决潜在的安全隐患。 在用设备的定期维护:对于在用的电气设备,电气安规分析仪可以用于定期维护和检测。通过测试设备的各项参数,可以及时发现设备
    发表于 12-24 14:13

    【「大模型启示录」阅读体验】营销领域大模型的应用

    今天跟随「大模型启示录」这本书,学习在营销领域应用大模型。 大模型通过分析大量的消费者数据,包括购买历史、浏览记录、社交媒体互动等,能够识别消费者的偏好和行为模式。这种分析能力有助于企业更好地理
    发表于 12-24 12:48

    自动零件分析仪的原理和应用

    。这有助于确保投入生产的原材料符合工艺要求,避免因原材料质量问题导致后续产品性能不佳。 加工过程监测:在金属加工过程中,分析仪能够持续监测金属的组织结构变化。例如,在锻造、轧制等热加工工序中,它能实时
    发表于 12-23 15:22

    系统化课程体系——2天倒计时!

    包括:电磁兼容、信号完整和电气安全。时域和频域分析有助于优化电磁问题。了解电流定律和电磁场原理有助于识别辐射源和传导路径。接地设计是减少
    的头像 发表于 12-16 09:52 825次阅读
    系统化课程体系——2天倒计时!

    红外感应单片机在智能卫浴的抗干扰分析

    一、自身优势带来的抗干扰潜力 自带恒流驱动电路 :XD08M3232单片机自带恒流驱动电路,这一特性可能有助于增强其在智能卫浴环境中的抗干扰。因为恒流驱动电路可以使相关感应部件的工作电流保持稳定
    发表于 12-14 15:41