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

    文章

    2104

    浏览量

    73500
  • 编译器
    +关注

    关注

    1

    文章

    1618

    浏览量

    49055
收藏 人收藏

    评论

    相关推荐

    鲁棒分析方法及其应用

    对输出的影响,找出最敏感的输入。这有助于识别哪些参数或输入对系统或算法的性能影响最大,从而在设计时给予更多的关注。 压力测试 :以超出正常范围的输入测试系统,找出崩溃或产生不可接受输出的临界点。这种方法能够模拟极端情况,评估
    的头像 发表于 11-11 10:21 285次阅读

    汽车异构硬件平台开发如何进行静态代码分析

    先进的静态代码分析工具,其新版本中引入的多CCT功能为开发人员提供了强大的支持,该功能不仅简化了多编译器环境下的代码分析过程,还可以极大增强
    的头像 发表于 10-09 16:15 456次阅读
    汽车异构硬件平台开发如何进行<b class='flag-5'>静态</b><b class='flag-5'>代码</b><b class='flag-5'>分析</b>

    多级宽带放大器各级之间pcb独立分开,信号线用sma线相接,电源线用普通铜线导线,有助于抗干扰吗?

    请问,多级宽带放大器各级之间pcb独立分开,信号线用sma线相接,电源线用普通铜线导线,有助于抗干扰么?
    发表于 09-05 06:35

    关于一些有助于优化电源设计的新型材料

    众所周知,人们对更高电源效率的追求正在推动性能的全方位提升。材料科学的进步对于优化电源设计和开发更高效、更紧凑和更可靠的解决方案发挥着关键作用。下文列出了一些有助于优化电源设计的新材料。
    的头像 发表于 08-29 15:26 351次阅读

    MSPM0-高级控制计时器有助于实现更好的控制和更好的数字输出

    电子发烧友网站提供《MSPM0-高级控制计时器有助于实现更好的控制和更好的数字输出.pdf》资料免费下载
    发表于 08-28 11:30 0次下载
    MSPM0-高级控制计时器<b class='flag-5'>有助于</b>实现更好的控制和更好的数字输出

    恒讯科技分析:香港站群服务器为什么要做伪静态处理呢?

    提高搜索引擎优化(SEO)效果:伪静态处理可以使得动态网页URL看起来像是静态网页的URL,这有助于搜索引擎更好地索引网站内容。搜索引擎通常偏好静态网页,因为它们认为
    的头像 发表于 07-31 12:49 212次阅读

    有助于提高网络设备性能的FRAM SF25C20(MB85RS2MT)

    有助于提高网络设备性能的FRAM SF25C20(MB85RS2MT)
    的头像 发表于 07-25 09:49 250次阅读
    <b class='flag-5'>有助于</b>提高网络设备性能的FRAM SF25C20(MB85RS2MT)

    国内低代码平台推荐--万界星空科技低代码平台

    代码平台是一种应用程序,它为编程提供图形用户界面,从而以极快的速度开发代码,减少传统编程工作。 这些工具有助于快速开发代码,最大限度地减少手工编码的工作量。这些平台不仅
    的头像 发表于 07-18 15:39 264次阅读
    国内低<b class='flag-5'>代码</b>平台推荐--万界星空科技低<b class='flag-5'>代码</b>平台

    爱普生的高精度传感技术有助于监控自动化

    Epson、JREast和NaganoKeiki联合开发了一种适用于铁路运营商的实用挠度监测设备-爱普生的高精度传感技术有助于监控自动化-SeikoEpsonCorporation(TSE:6724
    的头像 发表于 06-27 10:53 323次阅读
    爱普生的高精度传感技术<b class='flag-5'>有助于</b>监控自动化

    基于MM32F5270的Ethernet实现LwIP协议栈移植

    LwIP是轻量化的TCP/IP协议,由瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。LwIP具有高度可移植性代码开源,提供了三种编程接口(API):RAW API、NETCONN API 和 Socket API,用于与
    的头像 发表于 06-21 10:28 1098次阅读
    基于MM32F5270的Ethernet实现LwIP协议栈<b class='flag-5'>移植</b>

    FPGA的IP软核使用技巧

    够与所使用的FPGA平台和开发工具无缝集成。 阅读和理解IP软核的文档 : 在使用IP软核之前,务必仔细阅读和理解其提供的文档,包括用户手册、技术参考手册、示例代码等。这将有助于您更好地理解IP软核
    发表于 05-27 16:13

    在微芯片上使用3D反射器堆栈有助于加快6G通信的发展

    一项新的研究发现,在微芯片上使用3D反射器堆栈可以使无线链路的数据速率提高三倍,从而有助于加快6G通信的发展。
    的头像 发表于 03-13 16:31 641次阅读

    谷歌升级Bard AI聊天机器人为Gemini,新增Python代码编辑功能

     此外,谷歌表示,接下来数个月内,Gemini Advanced 计划会加入更多新功能,如支持更为详尽的上下文信息、增强多模态交互以及完善编程功能。据谷歌公开更新,付费用户可用 Gemini 界面直接编辑和执行 Python 代码
    的头像 发表于 02-20 15:47 547次阅读

    混合云策略的五个关键要素

    列举了有助于企业混合云策略取得成功的五个关键要素,包括更低的成本、广泛的可移植性、工作负载管理、工作负载整合和数据安全。
    的头像 发表于 01-23 14:44 632次阅读

    嵌入式开发为什么需要输出调试信息?

    、变量值、函数调用堆栈等信息,有助于快速定位和解决问题。2.实时反馈 在开发过程中逐步增加新功能或者修改现有功能时,输出调试信息可以提供实时反馈。这使得可以快速地检查修改的效果。 3.代码验证和逻辑分析
    发表于 11-28 16:46