tag 标签: 编码规范

相关帖子
相关博文
  • 热度 3
    2023-8-10 12:42
    1498 次阅读|
    0 个评论
    为什么 Linux 内核中不经常使用 typedef? 为什么 Linux 内核中不经常使用 typedef 我们在进行Linux驱动开发过程中,有没有出现过这样的报错? WARNING: do notaddnewtypedefs 不允许使用typedef! 虽然只是一个警告,但是如果你想往开源仓库提交代码,这就是一个必优化项。 那么,为什么Linux内核不建议使用typedef呢? 1、Linus Torvalds 的态度 On Mon, 10 Jun 2002, Linus Torvalds wrote: --snip/snip But in the end, maintainership matters. I personally don't want the typedef culture to get the upper hand, but I don't mind a few of them, and people who maintain their own code usually get the last word. to sum it up: using the "struct mystruct" is recommended , but not a must. Torvalds 本人不太想看到typedef文化占上风,但是维护自己代码的人通常有最后的发言权。 Torvalds 还是比较推荐使用struct mystruct的结构 不易理解 :使用typedef类型,不容易去理解变量的实际类型是什么样子的 不好维护 :由于Linux内核架构的庞大,不同架构之间定义的typedef类型可能并不具有通用性。 Torvalds 原文详见:https://lkml.indiana.edu/hypermail/linux/kernel/0206.1/0402.html 2、内核编码规范 从内核编码规范的角度,来看typedef 内核编码规范给出了typedef使用的一些场合: 完全不透明的对象:隐藏内部对象 明确的整数类型:抽象有助于避免混淆是int型还是long型,如u8/u16/u32 在某些特殊情况下,与标准C99类型相同的新类型。 可在用户空间中使用的类型 内核编码规范详见:https://www.kernel.org/doc/html/v4.10/process/coding-style.html 3、个人看法 个人感觉,从大型项目的开发维护上来说,typedef不建议使用,避免造成类型泛滥,也更加不容易理解。 对于个人开发的小项目,typedef可以完全看自己心情,毕竟typedef褒贬不一。 下面分享一些社区讨论帖子: 为什么我们要在C语言中频繁使用typedef:https://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c 为什么Linux编码锋哥不建议使用typedef:https://www.reddit.com/r/C_Programming/comments/dan8vr/why_does_the_linux_kernel_coding_style_guide/?rdt=36702 ▐ 我的圈子: 高级工程师聚集地
  • 热度 12
    2022-12-20 10:09
    1129 次阅读|
    0 个评论
    背景介绍 上一篇,我们聊了C++与AUTOSAR Coding Guidelines(点此回顾→ 当C++遇上AUTOSAR编码规范,你的安全我来护航-面包板社区 (eet-china.com) ,今天,咱们说说代码的网络信息安全。 可以说,智能化是当代汽车发展的必然趋势,为了增加乘用舒适性,现代汽车将车联网与智能车有机联合,搭载先进的车载传感器,控制器,执行 器等,并融合现代通信网络技术,实现车与人、车、路等智能信息的交换共享,V2X从此走进大众视野,开拓智能汽车的网联时代。 但,发展亦为挑战,面对日益增多的ECU,日趋庞大的车载代码,如何保证汽车应用信息安全?怎样才能不给黑客们可乘之机?这是一个严肃的议题,开发人员必须借助相关工具确保嵌入式代码的安全性,否则如下案例便是前车之鉴: 2013年,黑客通过Uconnect软件入侵数十万辆Fiat Chrysler,Fiat Chrysler最终在美国召回了140万辆汽车; 2015年,两名信息安全研究人员成功地在10英里外远程夺取了一辆Jeep Cherokee的控制权; 在刚刚过去的2018年,黑客盗取特斯拉与地图、遥测和车辆服务有关的专有数据,并利用特斯拉公共云入侵计算机系统植入挖矿运算程序。 据Upstream公司统计显示,从2010年到2018年,黑客针对智能汽车的攻击数量激增了6倍,“每一项连接到车上的新服务都为黑客提供了新的入侵途径”。 另据JuniperResearch预测,2019年拥有V2V功能的车辆总数逾110万辆,在未来四年内,其年复合增长率高达173%。到2023年,联网汽车数量将达到7.75亿辆,而无钥匙进入、娱乐系统、远程控制单元和连接智能手机等功能将会在更多的车型上配备。 所以,软件信息安全是现在及未来开发过程中的一大焦点。尽管软件工程师会设计诸如数据加密、身份验证协议等来减轻漏洞,但即便如此,软件也有可能存在隐患。为了保证软件安全,您需要从源码级别做起。 据软件工程研究所(Software Engineering Institute ,SEI卡内基梅隆大学研发中心,主要由美国国防部和国土安全部提供资金)估计,高达90%的安全事故都是由于黑客攻击了软件代码或者设计漏洞,黑客利用这些漏洞窃取私人数据,未经授权夺取系统控制权。 为了描述这是如何发生的,让我们举一个 例子 :C语言缓冲区溢出 什么是缓冲区溢出 当数据超出了既定内存的边界,就会发生溢出错误,比如: char buff ; buff = ‘a’; 这个例子中,声明了一个10字节的数组,但是程序想要索引第11个字节,超出已定义数组一个字节,如果邻近这一数组的内存区要在之后的程序里被占用,那么这种定义会导致不可预知的行为。 分布式网络缓冲区溢出如何吸引黑客 当一个程序运行时,它使用一个叫做“堆栈”的内存区域。当前执行函数作用域内的变量将存储在堆栈中。函数调用的地址也将被存储,以允许return语句返回到正确的位置。当函数返回给调用函数时,程序从它停止的地方继续执行。 因此,如果堆栈上的返回地址被修改为指向其他恶意指令,那么这些指令将在函数返回时执行。如果程序在接收数据(没有进行检查以确保输入缓冲区不会溢出),黑客就有可能设计一个包含恶意代码的输入或“有效负载”。这会使缓冲区溢出,并用恶意代码的地址覆盖堆栈上的返回地址。 所以,黑客可以利用缓冲区错误摧毁一个程序,篡改数据或者盗取信息。 预防安全漏洞至关重要 预防安全漏洞(如缓冲区溢出)至关重要并且是可以 实现的,那就是确保代码本身的编写没有可利用的漏洞。英文有句俗 ’ Putting stronger locks on your front door is no use if the windows are left open.’密码访问可以在一定程度上阻止黑客的攻击,但源码的安全才是最根本的保障。 如何保证C代码的网络信息安全 当聊到C的网络信息安全,我们首先会考虑以下3种编码规范: CERT C CERT 编码规范由软件工程研究所SEI 的CERT部门发布,它包含了编码和执行错误,还有低级的设计错误,旨在清除代码中可能导致网络安全的编码惯例以及未定义的行为。 CERT C每条规范包含: 标题 描述 不合规代码举例 合规代码解决方案举例 例外情形 CERT C这样定义漏洞:允许攻击者违反显式或隐式安全政策的一系列情况。缺陷可能很小,甚至可能都不影响软件的性能或者运行结果。然而它会在遭遇攻击的时候暴露问题,导致严重的安全后果。 Common Weakness Enumeration CWE(Common Weakness Enumeration)是从架构、设计、乃至编码层面描述代码中常见的网络安全问题。由美国MITRE公司发起。CWE可以作为识别、减少、预防漏洞的基线。 CWE按优先级排列漏洞列表。优先级最高的25个条目来自二十多个不同组织的统计数据,他们基于使用频率和重要性评估了每个C代码缺陷,很多CWE列 表中的缺陷都和缓冲溢出相关。我们的设计人员、编程者、测试者可以通过遵循CWE来消除典型错误,在编码阶段清除漏洞。 (ps: CERT及最新发布的CWE都包含针对C++的信息安全规范,在此不做详述) MISRA C MISRA编码规范由汽车工业软件可靠性协会发布,可以用来防止会导致安全问题和安全漏洞的错误编码,为安全相关系统的开发提供了最好的实践指导,可以说MISRA 是嵌入式系统最为理想的编码规范。目前应用最为广泛的MISRA C:2012 Amendment 1发布于2016年,它新增了C编码的安全指导,包括新的规则和指令,也包含了合规代码和不合规代码的举例说明。 既然以上三种编码规范都可以应用于C代码信息安全测试,那它们之间又有什么关联?还是举个栗子: MISRA C 2012 Rule 18.1 “A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand” 这条规则与CERT ARR30-C做的是同样的事情 CERT ARR30-C “Do not form or use out-of-bounds pointers or array subscripts.” 而这两条规则都与CWE C的多个典型安全漏洞相关,比如: CWE-119 “Improper Restriction of Operations within the Bounds of a Memory Buffer.” 也就是软件对内存缓冲区执行操作,但是它可以从缓冲区的预期边界之外的内存位置进行读写操作。 需要注意的是CERT C 是基于C11设计的,MISRA C 2012是基于C99设计的,MISRA C 2012-Addendum 3专门阐述了两者之间规则的异同点,具体数据如下图: 图1 CERT C & MISRA C 2012 规则覆盖汇总 以上数据汇总了CERT C和MISRA C 2012的规则覆盖情况,并根据规则覆盖强度分为: Strong :由CERT C规则处理的代码行为被一个或多个MISRA C2012规则覆盖 Weak :由CERT C规则处理的代码行为仅被一个或多个MISRA C2012指令/Rule1.3覆盖 None :独立于MISRA C 2012的CERT C规则 图2 部分CERT C & MISRA C 2012规则交叉示例 虽然MISRA C 2012对CERT C的覆盖达到了60%以上,但两者依据的C标准不同,且存在19%的差异,所以,各位大咖还要按需遵循。为此,Perforce(PRQA)公司建议了以下测试方案。 代码信息安全静态测试解决方案 结合工程实际,我们需要选择性遵循相关编码规范: 如果开发代码为C,并且要求综合全面的信息安全规则覆盖度,那么您需要同时执行MISRA C 2012(incl. Amendment 1)和CERT C 如果开发代码为C++且基于AUTOSAR架构,建议您全面执行AUTOSAR Coding Guidelines 如果您使用C++开发且要求遵循MISRA C++ 2008,那么建议您同时执行CERT C++,以保证所开发车辆的信息安全 以上静态测试方案的高效执行,还需借助强有力的静态代码分析器,才能避免CWE中的典型安全漏洞。作为代码静态测试领域的领跑者, Perforce(PRQA)公司的 Helix QAC无疑是各大厂商的第一选择。它可以自动执行MISRA、CERT、CWE、AUTOSAR Coding Guidelines等编码规范,拥有超过1600条诊断消息,每一条诊断消息都对应着一种违反规定的语言使用,并且提供详细的指标度量,以及可视化报表,量化代码质量,帮助测试人员深入了解数据流和控制流,大大提高静态测试效率,确保代码的信息安全。 如有需求,可联系北汇信息进行试用申请。北汇信息作为Perforce(PRQA)公司的合作伙伴,将为客户提供专业的静态代码测试工具和服务。 Perforce公司简介 Perforce(PRQA)公司是AUTOSAR组织在代码静态分析领域的唯一会员,负责功能安全软件架构的相关标准制定工作,参与编写了C++14编码指南,制定了AUTOSAR测试方案,并应用其开 发的静态测试工具Helix QAC在AUTOSAR Adaptive Platform演示代码上执行代码静态测试。 Helix QAC作为代码静态分析领域的先驱,不仅仅提供针对AUTOSAR C++的诊断,还支持MISRA C/C++、HICPP、JSF AV C++、CERT、CWE编码规范包,其精准的诊断消息和强大的软件生命周期管理平台为全球3000多个整车厂和零部件供应商所信赖。 参考文献 MISRA C:2012 – Addendum 3 Coverage of MISRA C:2012 (including Amendment 1) against CERT C 2016 Edition. 《当黑客盯上智能汽车》-汽车商业评论 How to write Secure C code. -Perforce
  • 热度 5
    2022-11-14 10:01
    1548 次阅读|
    0 个评论
    当飞鸟遇上游鱼,当溪流遇上江海,当北京遇上西雅图,当你遇上 Mr/Ms.Right…,“当”是一切美好的开端,但今天,咱先不聊自然也不聊爱情,聊一聊当C++遇上AUTOSAR编码规范,会有一段怎样的故事? AUTOSAR与静态代码测试 汽车界的同仁们都知晓,AUTOSAR(AUTomotive Open System ARchitecture)组织拥有超过180个会员,涵盖了汽车整车厂、零部件供应商、工具供应商、半导体芯片供应商等,这样的强强联合,开发了一套针对汽车ECU的开放式软件体系架构,实现了应用层和底层的解耦,标准化软件基本元素、接口及总线系统,使汽车行业能够在控制成本的同时,更好地应对系统复杂度不断增长的情况。 AUTOSAR组织开发的第一个开放式架构称为“Classic Platform”,该架构的开发以C代码为主体,在做代码静态测试时,应用MISRA C 2012足以。但随着智能化的普及,为了满足车联网及无人驾驶技术的发展需求, AUTOSAR组织推出新架构“Adaptive Platform”,Adaptive Platform的相关API接口由C++语言进行开发。那么问题来了,我们是否可以直接遵循MISRA C++编码规范? MISRA C++编码规范 许多安全关键性系统开发者结合已经建立的编码规范,典型如MISRA C++2008,来使用C++03语言标准,这无可厚非,MISRA C++2008的制定基础即为C++03。但C语言在持续更新,编译器也随之而变,这就意味着帮助开发人员编写安全可靠的代码的编码标准同样需要持续更新以保证新语言特性的最佳实践应用。 为此在2017年,AUTOSAR组织基于C++14标准发布了新的编码准则——AUTOSAR Coding Guidelines,这一准则是MISRA C++2008的延伸,它为应用现代C++语言编写安全和任务关键型嵌入式系统提供了有效指导。 其实AUTOSAR编码标准与MISRA C++2008存在高度的共性,在处理新语言特性的使用上存在少量差异,所以如果我们采用了合适的自动代码静态分析方案,完成MISRA C++2008到AUTOSAR Coding Guidelines的迁移并不是一件难事。 AUTOSAR Coding Guidelines 和现有编码规范的区别 和 联系 这应该是广大开发人员比较关心的一部分,用两个成语来概括AUTOSAR Coding Guidelines:兼容并蓄、独树一帜。因为它涉及了一系列已有的编程标准,又根据Adaptive Platform制定了独有的规则。2018年3月,AUTOSAR Coding Guidelines发布了402条规则,其中138条直接取自MISRA C++2008。 此外AUTOSAR还引用了如下编码标准: --Joint Strike Fighter Air Vehicle C++ coding standards (JSF AV C++) --High Integrity C++ coding standard Version 4.0 (HICPP) --CERT C++ coding standard (CERT) --C++ Core guidelines (C++ CORE) --Google C++ Style Guide 在AUTOSAR编码标准中,有“对已有编码标准的可追溯性”的章节,它详述了MISRA,HICPP,JSF,C++ Core guidelines,和CERT编码规则与AUTOSAR编码标准的关联度,并分成如下几类:“完全相同”、“微小差别”、“显著差别”、“不采用”,详见下表: AUTOSAR Coding Guidelines吸收了约91%的MISRA C++2008规则, 就如AUTOSAR编码规范Section 1所述:'This document is defined as an update of MISRA C++:2008 … MISRA C++:2008 is required prerequisite for the readers of this document.’。AUTOSAR Coding Guidelines是站在各位“巨人”的肩膀上推动AUTOSAR架构下汽车软件的发展和进步。 开发团队应该采用AUTOSAR编码规范吗? 很多人可能存在这样的疑问:能不能用MISRAC++2008测试C++14的代码?是否有必要采用AUTOSAR Coding Guidelines? 严格来讲,使用C++14编译器编译的代码是不能遵从MISRA规范的。如果用MISRAC++2008测试C++14的代码,就肯定会出现违反项,我们需要对每一项违反进行说明,并用其他方法再一次检查违反项代码。换句话说,是有可能证明C++14代码符合MISRA规范的,但过程很艰苦。AUTOSAR Coding Guidelines帮助开发人员摆脱了这种复杂情况。 所以,开发团队采用AUTOSAR编码规范是毋庸置疑的。不仅如此,如果您的项目需要按照C++14编码并且需要说明该项目符合ISO26262功能安全标准,那么AUTOSAR编码规范就是无可替代的,因为在AUTOSAR编码规范之前没有其他的编码标准是为了支持符合C++14编写的安全关键型软件而设计的。 下表是各编码规范支持的C++语言版本: 如何 实现从已有编码规范到AUTOSAR的转变? 答案很简单,按照AUTOSAR规范提示,修改源码。前提是您选择了靠谱的代码静态测试工具,才能得到精准的规范诊断信息,比如Helix QAC。在Helix QAC中,可以直接加载AUTOSAR编码规范,自动执行代码静态检测。 如果您已经遵循了MISRA编码规范,那意味着您已经完成了大部分工作,但不可避免的,在应用代码静态测试分析器做AUTOSAR规范检查时,分析器会在符合MISRA规范的代码里找到违反项,因为AUTOSAR编码标准引入了针对C++11/14特性的规范。这时候该举个例子了,比如: Rule A8-5-2: Braced-initialization {}, without equals sign, shall be used for variable initialization 在C++03的初始化中,是这样写的: int 32 x1 =0; 而AUTOSAR规范中不再兼容这种表达,取而代之的,是 std : : int 32_t x1{0}; 再比如: std : : int8_t c1=400; //ok? std : : int8_t c2 {400}; //error: narrowing conversion 这种初始化方式防止了缩小转换,提高了代码安全性,是C++新特性最佳实践应用的代表,然而这种规则检测MISRA C++是不支持的。 另外一个例子是: Rule A3-9-1: Fixed width integer types from , indicating the size and signedness, shall be used in place of the basic numerical types 这条规则取代了MISRA C++ Rule 3-9-2,MISRA C++依赖于用户或执行时定义的类型,而AUTOSAR则使用ISO C++标准中定义的类型。 其实说到这里,大家对AUTOSAR Coding Guidelines肯定有了更新的认识和判断。AUTOSAR编码规范之所以被应用,是因为在AUTOSAR架构下找不到合适的编程标准去指导现代C++(C++11/14)语言在安全关键性软件上的应用,典型如Adaptive Platform软件架构。现代C++提供了很多很有帮助的语言特性,当联合AUTOSAR编码规范一起使用时,可以帮助您提高代码的可读性,为嵌入式系统软件安全保驾护航。 这样看来,当C++遇上AUTOSAR编码规范,不失为汽车行业的一件大事。 如何开启浪漫的邂逅? 如需按照AUTOSAR编码规范进行测试,可联系北汇信息进行试用申请。北汇信息作为Perforce(PRQA)公司的合作伙伴,将为客户提供优质的静态代码测试工具和服务。 Perforce(PRQA)公司是AUTOSAR组织在代码静态分析领域的唯一会员,负责功能安全软件架构的相关标准制定工作,参与编写了C++14编码指南,制定了AUTOSAR测试方案,并应用其开发的静态测试工具Helix QAC在AUTOSAR Adaptive Platform演示代码上执行代码静态测试。 Helix QAC作为代码静态分析领域的先驱,不仅仅提供针对AUTOSAR C++的诊断,还支持MISRA C/C++、HICPP、JSF AV C++、CERT、CWE编码规范包,其精准的诊断消息和强大的软件生命周期管理平台为全球3000多个整车厂和零部件供应商所信赖。
  • 热度 8
    2022-10-13 10:48
    1042 次阅读|
    0 个评论
    汽车软件与C语言 随着软件定义汽车概念的兴起,汽车软件开发的工作量开始呈指数级增加,当前车载软件代码量已经达到1亿-3亿行。这是一个什么概念呢,相当于比Windows系统还高出一个数量级。据调查,大部分的车载软件都是使用C语言进行开发,因为C执行效率高、代码量小,因此在汽车的小型控制部件中被广泛使用。尽管C语言在嵌入式系统中如此流行,但仍有很多缺陷: 1. C是弱类型语言 C 是弱类型语言。 在 下面 代码中, char 类型 和 int 类型是可以直接运算的,因为 char 类型会被提升为 int ,这就是 C 中的隐式类型转换,将精度较小的转换为大精度的, 在 这个意义上讲,它并不符合强类型语言的定义。 # include int main ( void ){ char a ='a' ; int b =10 ; int c = a + b; return 0 ; } 2. C有更多操作符及优先级 C相较于其他的语言有更多的操作符,因此其也有更多不同的操作符优先级,其中的大多数都不是能直观判断的,所以通常会被程序员误解。 3. C程序一般不为常见问题提供运行时检查 ,例如运算异常(如零除),溢出,指针的有效性或者数组越界。 MISRA C编码规范 综上所述,C语言对于安全性要求很高的汽车软件而言是不安全的。汽车工业软件可靠性协会(Motor Industry Software Reliability Association,MISRA)在1998年发布了第一版针对汽车工业软件安全性的C语言编码规范---MISRA C, 让程序员有规范可 循 。 从1998年发布的MISRA C:1998,只针对汽车制造业的嵌入式开发,到MISRA C:2012,已经开始扩大覆盖范围到其他高安全性系统。 下面我们就看一下具体的MISRA C:2012规则内容。 MISRA C:2012规则介绍 MISRA C:2012 包含 159 条规则,其中 Directives 有 16 条, Rules 有 143 条。 Dir 4.12: 动态内存分配不应被使用。 图1 Dir 4.12规则 原理:任何库的动态内存分配和进程的释放都可能导致未定义的行为。 Rule 10.3:表达式的值不应分配给具有较窄基本类型或不同基本类型类别的对象。 图2 Rule 10.3规则 原理:C语言允许程序员有相当大的自由度,并允许自动形成不同算术类型之间的赋值。然而,使用这些隐式转换可能会导致意外的结果,可能会丢失值、符号或精度。如MISRA基本类型模型所强制的,使用更强的类型可以降低这些问题发生的可能性。 看到这里,相信大家有许多疑问:为什么一个是Dir而另一个是Rule呢?Category、Analysis这些又是什么呢?下面就来介绍一下MISRA规则的分类和属性。 MISRA C:2012规则分类 MISRA C:2012的规则按照性质分为两类:指令(Directives)和规则(Rules)。规则有三种不同类别:”强制(Mandatory)”、”要求(Required)”和“建议(Advisory)”;其中具体结果如下图所示。 图 3 MISRA C: 2012 规则分类 那么,在任何情况下都可以明确地说明该条代码违反了规则吗? 出于此问题,MISRA C:2012规则的Rules具有可判定性Decidable/Undecidable,他们的区分标准为是否能在任何情况下明确回答“该代码是否遵循了这条规则”? 图 4 MISRA C:2012 规则的可判定性 要注意的是,可判定性并不适用于Directives规则。 Rules 的分析范围 分为 Single Translation Unit/System : 图5 Rules的分析范围 Helix QAC与MISRA C:2012 很明显,MISRA C:2012规则就是为静态测试而生的。 Perforce 公司的静态分析工具 Helix QAC,是汽车行业中主流的静态分析器,其开发团队是MISRA C&C++编码委员会的创始会员,也是MISRA C&C++委员会最具影响力的会员。Helix QAC具有业界领先的编码规范覆盖度,目前MISRA C:2004的编码规范覆盖度达到了99%,而对MISRA C:2012的编码规范覆盖度已达到100%。是嵌入式静态分析领域公认的行业领导及先驱。 图6 Helix QAC的编码规范覆盖度 下面以开源工程wget为例,演示一下Helix QAC是如何定位违反MISRA C:2012规则的代码。 图7 Helix QAC诊断消息0883 诊断消息0883:“包含文件代码不受重复包含的保护”正是MISRAC:2012规则Dir 4.10的映射,通过诊断消息开发人员就可以了解到代码违反MISRA C:2012规则的情况,从而对代码进行修改使其合规。 图8 Rule 9.1规则的不同诊断消息 Rule 9.1:对象在初始化前不能被使用。 图9 Rule 9.1规则 这里大家或许会疑惑,为什么同一个规则下会产生两种诊断消息呢?答案是:数据流分析。 数据流分析是Helix QAC的高级分析,Helix QAC通过内置的数据流分析器 分析运 行 时的 行 为。数据流分析可以识别各种问题,包括可能指示编码错误的条件,以及可能导致程序崩溃的关键未定义 行 为。 我们可以看到图中的诊断消息2962和2963虽然都是Rule 9.1产生的,但是分成了 S uspicious和 A pparent两种。我们在代码中看一下这两条诊断消息的不同。 诊断消息2963的源码如下: 在226行声明了数组saved_lengths,241行对saved_lengths进行赋值操作,在255行使用saved_lengths。但saved_lengths的赋值操作不一定会进行,因为该操作在for循环中进行,如果for循环没有达到执行条件导致并未执行,那么此时saved_lengths就没有初始化。所以此条诊断消息是Suspicious。 诊断消息2962源码如下: 可以看到,在824行声明变量dt,但后面并未对dt进行初始化。所以此条诊断消息是Apparent。 由此可见Helix QAC数据流分析功能的强大。Helix QAC的数据流功能也在不断地更新,在即将到来的新版本2022.4中,数据流计划从Helix QAC引擎中分离出来,成为自己的组件。 在近期发布的最新版本Helix QAC 2022.3中, 引入了对微软Visual Studio 2022的支持 , 提供更广泛的编译器支持, 以及对C++20和C23的升级语言支持。 此外, 此版本具有使用“qainject”自动生成 CCT 的功能,可简化构建理解和编译器设置 。 作为Perforce公司的合作伙伴,北汇信息将为客户提供优质的静态代码测试工具和服务 。
  • 热度 14
    2013-6-19 16:29
    1834 次阅读|
    3 个评论
    前言:一篇关于编程命名的文章,分享给大家,尤其对于刚刚学习编程的人来讲,值得读一读:   编程初学者总是把大量的时间用在学习编程语言,语法,技巧和编程工具的使用上。他们认为,如果掌握了这些技术技巧,他们就能成为不错的程序员。然而,计算机编程的目的并不是关于精通这些技术、工具的,它是关于针对特定领域里的特定问题创造出相应的解决方案,程序员通过相互合作来实现这些。所以,很重要的一点,你需要能精确的用代码表达出你的思想,让其他人通过代码能明白你的意图。 让我们先 看看编程大师Robert C. Martin的杰作《Clean Code 》里的一句话:   “注释的目的是为了弥补代码自身在表达上的不足。” 这句话可以简单的理解为 如果你的代码需要注释,最有可能是你的代码写的很烂。 同样,如果在没有注释的情况下你无法用代码完整的表达你对一个问题或一个算法的思路,那这就是一个失败的信号。最终,这意味着你需要用注释来阐明一部分的思想,而这部分在代码里是看不出来的。 好的代码能够让任何人在不需要任何注释的情况下看懂。 好的编码风格能将所有有助于理解这个问题的所有信息都蕴含在代码里。 在编程理论中,有一个概念叫做“自我描述的源代码”。对于一段代码,一种常见的自我描述机制是遵循某种非严格定义的变量、方法、对象命名规则。这样做的主要作用就是使源代码更易读易懂。所以,也就更容易维护和扩展。 这篇文章里,我将举出一些例子,说明什么是“不好的代码”,什么是“清楚的代码” 命名要能揭示意图如何命名,在编程中这永远都是个老大难问题。有些程序员喜欢简化、缩短或加密名称,使得只有他们自己能懂。下面让我们看一些例子: 不好的代码: int d; // 天数 int ds; int dsm; int faid;“d”可以表示任何东西。作者使用注释来表明他的意图,却没有选择用代码来表示。而“faid”很容易导致误解为ID。 清楚的代码: int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays;命名时避免含义引起误解的信息错误的信息比没有信息更糟糕。有些程序员喜欢“隐藏”一些重要信息,有时候他们也会写出一些让人误解的代码。 不好的代码: Customer customers; Table customers;命名要有合适的长度在高级编程语言中,变量名的长度通常不太限制。变量名几乎可以任何长度。虽然如此,这也可能使代码变得闹心。 不好的代码: var theCustomersListWithAllCustomersIncludedWithoutFilter; var list;好的名称应该只含有必要的词汇来表达一个概念。任何不必要的字词都会使名称变长、难于理解。名称越短越好,前提是能在上下文中表达完整的意思(下订单这个场景中,“customersInOrder” 要比 “list” 好)。 清楚的代码: var allCustomers; var customersInOrder;命名时编码规范保持一致,让规范帮助理解代码所有的编程技术(语言)都有自己的“风格”,叫做编码规范。程序员应该在写代码时遵循这些习惯,因为其他的程序员也知道这些,并按这种风格编写。下面我们看一个没有明显规范的不好的代码例子。下面的这段代码没有遵循很好的已知的“编码规范”(比如PascalCase, camelCase, Hungarian规范)。更糟糕的是,这有一个毫无意义的bool变量“change”。这是个动词(用来描述动作),但这里的bool值是来描述一个状态,所以,这里应该用一个形容词更合适。 不好的代码: const int maxcount = 1 bool change = true public interface Repository private string NAME public class personaddress void getallorders()一段代码,只看它的一部分,你就应该直接明白它是什么类型,只需要看它的命名方法。 例如:你看到了“_name”,你就能知道它是个私有变量。你应该在任何地方都利用这种表示方法,没有例外情况。 清楚的代码: const int MAXCOUNT = 1 bool isChanged = true public interface IRepository private string _name public class PersonAddress void GetAllOrders()命名时相同的概念用相同的词表达定义概念很难。在软件开发过程中,很多时间都花在分析业务场景、思考正确的定义里面所有的元素。这些概念永远都是让程序员头痛的事。 不好的代码: //1. void LoadSingleData() void FetchDataFiltered() Void GetAllData() //2. void SetDataToView(); void SetObjectValue(int value) 首先: 代码的作者试图表达“get the data”的概念,他使用了多个词“load”,“getch”,“get”。一个概念只用一个词表达就行了(在同一个场景中)。 第二: “set”这个词用在了2个概念里:第一是“data loading to view”,第二个是“setting a value of object”。这是两个不同的概念,你应该使用不同的词。 清楚的代码: //1. void GetSingleData() void GetDataFiltered() Void GetAllData() //2. void LoadDataToView(); void SetObjectValue(int value)命名时使用跟业务领域相关的词程序员写的所有代码都是跟业务领域场景逻辑相连的。为了让所有关系到这个问题的人都能更好的理解,程序中应该使用在领域环境中有意义的名称。 不好的代码: public class EntitiesRelation { Entity o1; Entity o2; }当在编写针对某个领域的代码时,你应该始终考虑使用领域有联系的名称。在将来,当另外一个人(不仅是程序员,也许是测试人员)接触你的代码时,他能轻松的理解这个业务领域里你的代码是什么意思(不需要业务逻辑知识)。你首先考虑的应该是业务问题,之后才是如何解决。 清楚的代码: public class ProductWithCategory { Entity product; Entity category; }命名时使用在特定环境里有意义的词代码里名称都有自己的上下文。上下文对于理解一个名称非常重要,因为它能提供额外的信息。让我们来看看一个典型的“地址”上下文: 不好的代码: string addressCity; string addressHomeNumber; string addressPostCode;在大多数情况中,“Post Code”通常是地址的一部分,很显然,邮政编码不能单独使用(除非你是在开发一个专门处理邮编的应用)。所以,没有必要在“PostCode”的前面加上“address”。更重要的,所以的这些信息都有一个上下文容环境,一个命名空间,一个类。 在面向对象编程中,这里应该用一个“Address”类来表达这个地址信息。 清楚的代码: class Address { string city; string homeNumber; string postCode; }命名方法总结概述起来,做为一个程序员,你应该: 命名是来表达概念的 注意名称长度,名称里只该含有必要的词语 编码规范有助于理解代码,你应该使用它 名称不要混用 名称在业务领域里要有意义,在上下文里有意义 viahttp://www.aqee.net/express-names-in-code-bad-vs-clean/