logo资料库

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

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