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++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72899
  • 编译器
    +关注

    关注

    1

    文章

    1576

    浏览量

    48606
收藏 人收藏

    评论

    相关推荐

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

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

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

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

    ADI全新集成电路有助于监测心率

    电子发烧友网站提供《ADI全新集成电路有助于监测心率.pdf》资料免费下载
    发表于 11-24 10:38 0次下载
    ADI全新集成电路<b class='flag-5'>有助于</b>监测心率

    R课堂 | 有助于车载和工业设备降低功耗!内置SiC二极管的IGBT

    本文的关键要点 ・要想实现碳中和,就需要进一步提高DC-DC转换器等功率转换系统的效率。 ・ 集IGBT和SiC肖特基势垒二极管于一身的“Hybrid IGBT”,可同时实现高效率和低成本,有助于
    的头像 发表于 11-15 16:05 216次阅读
    R课堂 | <b class='flag-5'>有助于</b>车载和工业设备降低功耗!内置SiC二极管的IGBT

    多层pcb生产,更有助于高精度布线

    多层pcb生产,更有助于高精度布线
    的头像 发表于 11-15 11:02 249次阅读

    分享一款不错的嵌入式静态代码扫描工具

    之前给大家分享过嵌入式开发常用的代码静态分析工具,比如:PC-lint、LDRA、VectorCAST等。
    的头像 发表于 10-16 15:39 1032次阅读
    分享一款不错的嵌入式<b class='flag-5'>静态</b><b class='flag-5'>代码</b>扫描工具

    静态代码块、构造代码块、构造函数及普通代码块的执行顺序

    在Java中,静态代码块、构造代码块、构造函数、普通代码块的执行顺序是一个笔试的考点,通过这篇文章希望大家能彻底了解它们之间的执行顺序。 1、静态
    的头像 发表于 10-09 15:40 431次阅读
    <b class='flag-5'>静态</b><b class='flag-5'>代码</b>块、构造<b class='flag-5'>代码</b>块、构造函数及普通<b class='flag-5'>代码</b>块的执行顺序

    激光脉冲或将有助于开发下一代高容量电池

    近日,阿卜杜拉国王科技大学(King Abdullah University,KAUST)了一项研究成果,该成果可能有助于改进下一代电池的阳极材料。
    发表于 08-08 14:44 188次阅读

    什么是静态代码分析静态代码分析概述

    静态分析可帮助面临压力的开发团队。高质量的版本需要按时交付。需要满足编码和合规性标准。错误不是一种选择。 这就是开发团队使用静态分析工具/源代码
    的头像 发表于 07-19 12:09 921次阅读
    什么是<b class='flag-5'>静态</b><b class='flag-5'>代码</b><b class='flag-5'>分析</b>?<b class='flag-5'>静态</b><b class='flag-5'>代码</b><b class='flag-5'>分析</b>概述

    孔环是什么?深入了解孔环有助于实现PCB设计

    本文将探讨孔环,因为更深入的了解孔环有助于确保成功地实现PCB设计。
    的头像 发表于 07-19 10:21 2705次阅读
    孔环是什么?深入了解孔环<b class='flag-5'>有助于</b>实现PCB设计

    Maxim芯片有助于设计人员降低系统功耗

    已经成为设计者追求的新目标,特别是对于每天工作24小时的系统。为了满足低功耗要求,电路设计人员深知细节决定成败,需要对每一部分电路的电流进行仔细测算。本文介绍了Maxim芯片在典型系统中的应用,有助于设计人员降低系统功耗。文中给出的实例只是Maxim众多超低电流器件中的几个典型例子。
    的头像 发表于 06-10 09:31 526次阅读
    Maxim芯片<b class='flag-5'>有助于</b>设计人员降低系统功耗

    深入浅出OkHttp源码解析及应用实践

    OkHttp 在 Java 和 Android 世界中被广泛使用,深入学习源代码有助于掌握软件特性和提高编程水平。
    的头像 发表于 06-08 15:47 348次阅读
    深入浅出OkHttp源码解析及应用实践

    PCB印刷电路板打样的重要

    似乎是一个额外的步骤,但PCB打样会在您开始全面生产运行之前对印刷电路板进行预生产分析。那么,PCB打样在电子产品研发过程中有哪些重要呢? 1.加快整体生产 高度准确的PCB原型有助于最大限度地减少
    发表于 06-07 16:37

    209 桥式整流各环节的电流分析有助于元件选择#硬声创作季

    电工技术
    或许
    发布于 :2023年06月06日 08:50:43

    Linux内核代码静态检查

    Linus在2004年开发了kernel代码静态检查工具,可以检查出kernel中潜在的风险代码
    的头像 发表于 06-05 14:50 713次阅读