华为技术有限公司c语言编程规范.docx





《华为技术有限公司c语言编程规范.docx》由会员分享,可在线阅读,更多相关《华为技术有限公司c语言编程规范.docx(61页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd.密级:confidentiality level DKBA 2826-2011.5修订声明Revision declaration本规范拟制与解释部门:本规范的相关系列规范或文件:相关国际规范或文件一致性: 替代或作废的其它规范或文件:相关规范或文件的相互关系:规范号主要起草部门专家主要评审部门专家修订情况DKBAxxxx.x-xxxx.xxPSST质量部:郭曙光00121837PSST质量部:李
2、重霄00117374郭永生00120218核心网:张进柏00120359中研:张建保00116237无线:苏光牛00118740郑铭00118617 陶永祥00120482软件公司:周代兵00120359刘心红00118478朱文琦00172539网络:王玎00168059黄维东49827 IP开发部: 饶远00152313网络:张伟00118807 周灿00056781王晶00041937陈艺彪00036913IP开发部:薛治00038309核心网:张小林00058208王德喜00040674李明胜00042021软件公司:文 滔00119601无线:刘爱华00162172中研:谭洪0016
3、26542011-06-02华为机密,未经许可不得扩散 Huawei Confidential 第23页,共61页Page 23 , Total61目 录Table of Contents0 规范制订说明50.1 前言50.2 代码总体原则50.3 规范实施、解释60.4 术语定义61 头文件62 函数123 标识符命名与定义213.1 通用命名规则213.2 文件命名规则233.3 变量命名规则233.4 函数命名规则243.5 宏的命名规则244 变量255 宏、常量286 质量保证327 程序效率368 注释399 排版与格式4410 表达式4611 代码编辑、编译4912 可测性501
4、3 安全性5113.1 字符串操作安全5113.2 整数安全5213.3 格式化输出安全5613.4 文件I/O安全5713.5 其它5914 单元测试5915 可移植性6016 业界编程规范60C语言编程规范范 围:本规范适用于公司内使用C语言编码的所有软件。本规范自发布之日起生效,以后新编写的和修改的代码应遵守本规范。简 介:本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。0 规范制订说明0.1 前言为提高产品代码质量,指导广大软件开发人员编写出简洁、可维护、可靠、可测试、高效、可移植的代码,编程规范修
5、订工作组分析、总结了我司的各种典型编码问题,并参考了业界编程规范近年来的成果,重新对我司1999年版编程规范进行了梳理、优化、刷新,编写了本规范。本规范将分为完整版和精简版,完整版将包括更多的样例、规范的解释以及参考材料(what & why),而精简版将只包含规则部分(what)以便查阅。在本规范的最后,列出了一些业界比较优秀的编程规范,作为延伸阅读参考材料。0.2 代码总体原则1、清晰第一清晰性是易于维护、易于重构的程序必需具备的特征。代码首先是给人读的,好的代码应当可以像文章一样发声朗诵出来。目前软件维护期成本占整个生命周期成本的40%90%。根据业界经验,维护期变更代码的成本,小型系统
6、是开发期的5倍,大型系统(100万行代码以上)可以达到100倍。业界的调查指出,开发组平均大约一半的人力用于弥补过去的错误,而不是添加新的功能来帮助公司提高竞争力。“程序必须为阅读它的人而编写,只是顺便用于机器执行。”Harold Abelson 和 Gerald Jay Sussman“编写程序应该以人为本,计算机第二。”Steve McConnell本规范通过后文中的原则(如头优秀的代码可以自我解释,不通过注释即可轻易读懂/头文件中适合放置接口的声明,不适合放置实现/除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音)、规则(如防止局部变量与全局变量同名)等说明清晰的重要性。一般情况
7、下,代码的可阅读性高于性能,只有确定性能是瓶颈时,才应该主动优化。 2、简洁为美简洁就是易于理解并且易于实现。代码越长越难以看懂,也就越容易在修改时引入错误。写的代码越多,意味着出错的地方越多,也就意味着代码的可靠性越低。因此,我们提倡大家通过编写简洁明了的代码来提升代码可靠性。废弃的代码(没有被调用的函数和全局变量)要及时清除,重复代码应该尽可能提炼成函数。本规范通过后文中的原则(如文件应当职责单一/一个函数仅完成一件功能)、规则(重复代码应该尽可能提炼成函数/避免函数过长,新增函数不超过50行)等说明简洁的重要性。3、选择合适的风格,与代码原有风格保持一致产品所有人共同分享同一种风格所带来
8、的好处,远远超出为了统一而付出的代价。在公司已有编码规范的指导下,审慎地编排代码以使代码尽可能清晰,是一项非常重要的技能。如果重构/修改其他风格的代码时,比较明智的做法是根据现有代码的现有风格继续编写代码,或者使用格式转换工具进行转换成公司内部风格。0.3 规范实施、解释本规范制定了编写C语言程序的基本原则、规则和建议。本规范适用于公司内使用C语言编码的所有软件。本规范自发布之日起生效,对以后新编写的和修改的代码应遵守本规范。本规范由质量体系发布和维护。实施中遇到问题,可以到论坛 在某些情况下(如BSP软件)需要违反本文档给出的规则时,相关团队必须通过一个正式的流程来评审、决策规则违反的部分,
9、个体程序员不得违反本规范中的相关规则。0.4 术语定义原则:编程时必须坚持的指导思想。规则:编程时强制必须遵守的约定。建议:编程时必须加以考虑的约定。说明:对此原则/规则/建议进行必要的解释。示例:对此原则/规则/建议从正、反两个方面给出例子。延伸阅读材料:建议进一步阅读的参考材料。1 头文件背景对于C语言来说,头文件的设计体现了大部分的系统设计。不合理的头文件布局是编译时间过长的根因,不合理的头文件实际上不合理的设计。术语定义:依赖:本章节特指编译依赖。若x.h包含了y.h,则称作x依赖y。依赖关系会进行传导,如x.h包含y.h,而y.h又包含了z.h,则x通过y依赖了z。依赖将导致编译时间
10、的上升。虽然依赖是不可避免的,也是必须的,但是不良的设计会导致整个系统的依赖关系无比复杂,使得任意一个文件的修改都要重新编译整个系统,导致编译时间巨幅上升。在一个设计良好的系统中,修改一个文件,只需要重新编译数个,甚至是一个文件。某产品曾经做过一个实验,把所有函数的实现通过工具注释掉,其编译时间只减少了不到10%,究其原因,在于A包含B,B包含C,C包含D,最终几乎每一个源文件都包含了项目组所有的头文件,从而导致绝大部分编译时间都花在解析头文件上。某产品更有一个“优秀实践”,用于将.c文件通过工具合并成一个比较大的.c文件,从而大幅度提高编译效率。其根本原因还是在于通过合并.c文件减少了头文件
11、解析次数。但是,这样的“优秀实践”是对合理划分.c文件的一种破坏。大部分产品修改一处代码,都得需要编译整个工程,对于TDD之类的实践,要求对于模块级别的编译时间控制在秒级,即使使用分布式编译也难以实现,最终仍然需要合理的划分头文件、以及头文件之间的包含关系,从根本上降低编译时间。google C+ Style Guide1.2 头文件依赖 章节也给出了类似的阐述:若包含了头文件aa.h,则就引入了新的依赖:一旦aa.h被修改,任何直接和间接包含aa.h代码都会被重新编译。如果aa.h又包含了其他头文件如bb.h,那么bb.h的任何改变都将导致所有包含了aa.h的代码被重新编译,在敏捷开发方式下
12、,代码会被频繁构建,漫长的编译时间将极大的阻碍频繁构建。因此,我们倾向于减少包含头文件,尤其是在头文件中包含头文件,以控制改动代码后的编译时间。合理的头文件划分体现了系统设计的思想,但是从编程规范的角度看,仍然有一些通用的方法,用来合理规划头文件。本章节介绍的一些方法,对于合理规划头文件会有一定的帮助。原则1.1 头文件中适合放置接口的声明,不适合放置实现。说明:头文件是模块(Module)或单元(Unit)的对外接口。头文件中应放置对外部的声明,如对外提供的函数声明、宏定义、类型定义等。内部使用的函数(相当于类的私有方法)声明不应放在头文件中。内部使用的宏、枚举、结构定义不应放入头文件中。变
13、量定义不应放在头文件中,应放在.c文件中。变量的声明尽量不要放在头文件中,亦即尽量不要使用全局变量作为接口。变量是模块或单元的内部实现细节,不应通过在头文件中声明的方式直接暴露给外部,应通过函数接口的方式进行对外暴露。即使必须使用全局变量,也只应当在.c中定义全局变量,在.h中仅声明变量为全局的。延伸阅读材料:C语言接口与实现(David R. Hanson 著 傅蓉 周鹏 张昆琪 权威 译 机械工业出版社 2004年1月)(英文版: C Interfaces and Implementations)原则1.2 头文件应当职责单一。说明:头文件过于复杂,依赖过于复杂是导致编译时间过长的主要原因
14、。很多现有代码中头文件过大,职责过多,再加上循环依赖的问题,可能导致为了在.c中使用一个宏,而包含十几个头文件。示例:如下是某平台定义WORD类型的头文件: #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef unsigned short WORD;这个头文件不但定义了基本数
15、据类型WORD,还包含了stdio.h syslib.h等等不常用的头文件。如果工程中有10000个源文件,而其中100个源文件使用了stdio.h的printf,由于上述头文件的职责过于庞大,而WORD又是每一个文件必须包含的,从而导致stdio.h/syslib.h等可能被不必要的展开了9900次,大大增加了工程的编译时间。原则1.3 头文件应向稳定的方向包含。说明:头文件的包含关系是一种依赖,一般来说,应当让不稳定的模块依赖稳定的模块,从而当不稳定的模块发生变化时,不会影响(编译)稳定的模块。就我们的产品来说,依赖的方向应该是:产品依赖于平台,平台依赖于标准库。某产品线平台的代码中已经包
16、含了产品的头文件,导致平台无法单独编译、发布和测试,是一个非常糟糕的反例。除了不稳定的模块依赖于稳定的模块外,更好的方式是两个模块共同依赖于接口,这样任何一个模块的内部实现更改都不需要重新编译另外一个模块。在这里,我们假设接口本身是最稳定的。延伸阅读材料:编者推荐开发人员使用“依赖倒置”原则,即由使用者制定接口,服务提供者实现接口,更具体的描述可以参见敏捷软件开发:原则、模式与实践(Robert C.Martin 著 邓辉 译 清华大学出版社2003年9月) 的第二部分“敏捷设计”章节。规则1.1 每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。说明:如果一个.c文件不需要对外
17、公布任何接口,则其就不应当存在,除非它是程序的入口,如main函数所在的文件。现有某些产品中,习惯一个.c文件对应两个头文件,一个用于存放对外公开的接口,一个用于存放内部需要用到的定义、声明等,以控制.c文件的代码行数。编者不提倡这种风格。这种风格的根源在于源文件过大,应首先考虑拆分.c文件,使之不至于太大。另外,一旦把私有定义、声明放到独立的头文件中,就无法从技术上避免别人include之,难以保证这些定义最后真的只是私有的。本规则反过来并不一定成立。有些特别简单的头文件,如命令ID定义头文件,不需要有对应的.c存在。示例:对于如下场景,如在一个.c中存在函数调用关系:void foo()b
18、ar();void bar()Do something;必须在foo之前声明bar,否则会导致编译错误。这一类的函数声明,应当在.c的头部声明,并声明为static的,如下: static void bar();void foo()bar();void bar()Do something;规则1.2 禁止头文件循环依赖。说明:头文件循环依赖,指a.h包含b.h,b.h包含c.h,c.h包含a.h之类导致任何一个头文件修改,都导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。而如果是单向依赖,如a.h包含b.h,b.h包含 c.h,而c.h不包含任何头文件,则修改a.h不会导致包含了b
19、.h/c.h的源代码重新编译。规则1.3 .c/.h文件禁止包含用不到的头文件。说明:很多系统中头文件包含关系复杂,开发人员为了省事起见,可能不会去一一钻研,直接包含一切想到的头文件,甚至有些产品干脆发布了一个god.h,其中包含了所有头文件,然后发布给各个项目组使用,这种只图一时省事的做法,导致整个系统的编译时间进一步恶化,并对后来人的维护造成了巨大的麻烦。规则1.4 头文件应当自包含。说明:简单的说,自包含就是任意一个头文件均可独立编译。如果一个文件包含某个头文件,还要包含另外一个头文件才能工作的话,就会增加交流障碍,给这个头文件的用户增添不必要的负担。示例:如果a.h不是自包含的,需要包
20、含b.h才能编译,会带来的危害:每个使用a.h头文件的.c文件,为了让引入的a.h的内容编译通过,都要包含额外的头文件b.h。额外的头文件b.h必须在a.h之前进行包含,这在包含顺序上产生了依赖。注意:该规则需要与“.c/.h文件禁止包含用不到的头文件”规则一起使用,不能为了让a.h自包含,而在a.h中包含不必要的头文件。a.h要刚刚可以自包含,不能在a.h中多包含任何满足自包含之外的其他头文件。规则1.5 总是编写内部#include保护符(#define 保护)。说明:多次包含一个头文件可以通过认真的设计来避免。如果不能做到这一点,就需要采取阻止头文件内容被包含多于一次的机制。通常的手段是
21、为每个文件配置一个宏,当头文件第一次被包含时就定义这个宏,并在头文件被再次包含时使用它以排除文件内容。所有头文件都应当使用#define 防止头文件被多重包含,命名格式为FILENAME_H,为了保证唯一性,更好的命名是PROJECTNAME_PATH_FILENAME_H。注:没有在宏最前面加上“_,即使用FILENAME_H代替_FILENAME_H_,是因为一般以_和” 开头的标识符为系统保留或者标准库使用,在有些静态检查工具中,若全局可见的标识符以_开头会给出告警。定义包含保护符时,应该遵守如下规则: 1)保护符使用唯一名称;2)不要在受保护部分的前后放置代码或者注释。示例:假定VOS
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华为技术 有限公司 语言 编程 规范

限制150内