type
date
slug
category
icon
password
头文件
原则
- 头文件中放置接口声明,不放置实现
- 内部使用的函数声明不放在头文件中。
- 内部使用的宏、枚举、结构定义不应放入头文件中。
- 变量定义不应放在头文件中,应放在.c文件中。
- 变量的声明尽量不要放在头文件中,亦即尽量不要使用全局变量作为接口。
- 必须使用全局变量,也只应当在.c中定义全局变量,在.h中仅声明变量为全局的。
- 头文件应职责单一
- 头文件不宜过大,职责过多再加上循环依赖,会导致编译时间过长。
规则
- 每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。
- 如果一个.c文件不需要对外公布任何接口,则其就不应当存在,除非它是程序的入口,如main函数所在的文件。
- 本规则反过来并不一定成立。有些特别简单的头文件,如命令ID定义头文件,不需要有对应的.c存在。
- 内部使用的函数声明不放在头文件中,放在.c 中声明static
- 禁止头文件循环依赖
头文件循环依赖,指a.h包含b.h,b.h包含c.h,c.h包含a.h之类导致任何一个头文件修改,都
导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。
- .c/.h文件禁止包含用不到的头文件
- 头文件应当自包含。
自包含就是任意一个头文件均可独立编译。如果一个文件包含某个头文件,还要包含另外一个头文件才能工作的话,就会增加交流障碍,给这个头文件的用户增添不必要的负担。
- 总是编写内部#include保护符(#define 保护)。
- 保护符使用唯一名称,命名是PROJECTNAME_PATH_FILENAME_H_;
- 不要在受保护部分的前后放置代码或者注释,例外情况:版权声明部分以及头文件的整体注释部分(如阐述此头文件的开发背景、使用注意事项等)可以放在保护符(#ifndef XX_H)前面。
假定VOS工程的timer模块的timer.h,其目录为VOS/include/timer/timer.h,应按如下方式保护
- 禁止在头文件中定义变量。
- 只能通过包含头文件的方式使用其他.c提供的接口,禁止在.c中通过extern的方式使用外部函数接口、变量。
- 禁止在extern "C"中包含头文件。
建议
- 一个模块通常包含多个.c文件,建议放在同一个目录下,目录名即为模块名。为方便外部使用者,建议每一个模块提供一个.h,文件名为目录名。
- 如果一个模块包含多个子模块,则建议每一个子模块提供一个对外的.h,文件名为子模块名。说明:降低接口使用者的编写难度。
- 同一产品统一包含头文件排列方式。
- 说明:常见的包含头文件排列方式:功能块排序、文件名升序、稳定度排序。
- 以升序方式排列头文件可以避免头文件被重复包含,如:
- 以稳定度排序,建议将不稳定的头文件放在前面,如把产品的头文件放在平台的头文件前面,如下:
相对来说,product.h修改的较为频繁,如果有错误,不必编译platform.h就可以发现product.h的错误,可以部分减少编译时间。
函数
原则
- 一个函数仅完成一件功能。
- 重复代码应该尽可能提炼成函数。
规则
- 避免函数过长,新增函数不超过50行(非空非注释行)。
- 避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。
- 可重入函数应避免使用共享变量;若需要使用,则应通过互斥手段(关中断、信号量)对其加以保护。
- 包含全局变量,不具有可重入性
b. 改进措施
- 对参数的合法性检查,由调用者负责还是由接口函数负责,应在项目组/模块内应统一规定。缺省由调用者负责。
- 对函数的错误返回码要全面处理。
- 立刻检查错误提示
- 设计高扇入,合理扇出(小于7)的函数。
- 废弃代码(没有被调用的函数和变量)要及时清除
建议
- 函数不变参数使用const。
- 函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用。
- 函数的static局部变量是函数的内部存储器,可能使函数的功能不可预测
- 当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类,则返回为错针。
- 如下函数,其返回值(即功能)是不可预测的。
- 检查函数所有非参数输入的有效性,如数据文件、公共变量等。
- 参数输入
- 非参数输入:全局变量、数据文件的输入
- 函数的参数个数不超过5个。
- 除打印类函数外,不要使用可变长参函数。
- 在源文件范围内声明和定义的所有函数,除非外部可见,否则应该增加static关键字。
建议定义一个STATIC宏,在调试阶段,将STATIC定义为static,版本发布时,改为空,以便于后续的打热补丁等操作
文件与目录
注释规范
排版与格式
3 命名规范
通用命名
目前比较使用的如下几种命名风格:
- unix like风格:单词用小写字母,每个单词直接用下划线„_‟分割,例如text_mutex,kernel_text_address。
- Windows风格:大小写字母混用,单词连在一起,每个单词首字母大写。不过Windows 风格如果遇到大写专有用语时会有些别扭,例如命名一个读取RFC文本的函数,命令为ReadRFCText,看起来就没有unix like的read_rfc_text清晰了
原则
- 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。
int error_number;
int number_of_completed_connection;
int n;
int nerr;
int n_comp_conns;
- 除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。
一些常见可以缩写的例子:
规则
- 产品/项目组内部应保持统一的命名风格。 确定Unix like和windows like风格一种,并在产品内部保持一致。
建议
- 用正确的反义词组命名具有互斥意义的变量或相反动作的函数等
- 尽量避免名字中出现数字编号,除非逻辑上的确需要编号。
#define EXAMPLE_UNIT_TEST_
#define EXAMPLE_ASSERT_TEST_
#define EXAMPLE_0_TEST_
#define EXAMPLE_1_TEST_
- 标识符前不应添加模块、项目、产品、部门的名称作为前缀。
- 平台/驱动等适配代码的标识符命名风格保持和平台/驱动一致。
- 重构/修改部分代码时,应保持和原有代码的命名风格一致。
文件命名
建议
- 文件命名统一采用小写字符。
变量命名
规则
- 全局变量应增加“g_”前缀。
- 静态变量应增加“s_”前缀。
- 禁止使用单字节命名变量,但允许定义i、j、k作为局部循环变量。
建议
- 不建议使用匈牙利命名法。
- 添加变量类型,降低了变量的可读性
- 修改变量类型定义后,所有使用该变量的地方都需要修改。
- 使用名词或者形容词+名词方式命名变量。
函数命名
建议
- 函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。
- 函数指针除了前缀,其他按照函数的命名规则命名。
宏的命名
规则
- 对于数值或者字符串等等常量的定义,建议采用全大写字母,单词之间加下划线 “_” 的方式命名(枚举同样建议使用此方式定义)。
- 除了头文件或编译开关等特殊标识定义,宏定义不能使用下划线“_”开头和结尾。
变量
原则
- 一个变量只有一个功能,不能把一个变量用作多种用途。
WORD DelRelTimeQue(void)
{
WORD Ret;
WORD Locate;
Locate = 3;
Ret = DeleteFromQue(Locate);
return Ret;
}
WORD DelRelTimeQue(void)
{
WORD Locate;
Locate = 3;
Locate = DeleteFromQue(Locate); /* Locate具有两种功能:位置和函数 DeleteFromQue的返回值 */
return Locate;
}
- 结构功能单一;不要设计面面俱到的数据结构。
相关的一组信息才是构成一个结构体的基础,结构的定义应该可以明确的描述一个对象,而不是一组相关性不强的数据的集合。
- 不用或者少用全局变量。
规则
- 防止局部变量与全局变量同名。
- 通讯过程中使用的结构,必须注意字节序。
通讯报文中,字节序是一个重要的问题,我司设备使用的cpu类型复杂多样,大小端、32位/64位的处理器也都有,如果结构会在报文交互过程中使用,必须考虑字节序问题。
- 严禁使用未经初始化的变量作为右值。
建议
- 构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的全局变量,防止多个不同模块或函数都可以修改、创建同一全局变量的现象。
- 使用面向接口编程思想,通过API访问数据:如果本模块的数据需要对外部模块开放,应提供接口函数来设置、获取,同时注意全局数据的访问互斥。
- 在首次使用前初始化变量,初始化的地方离使用的地方越近越好。
- 明确全局变量的初始化顺序,避免跨模块的初始化依赖。
- 尽量减少没有必要的数据类型默认转换与强制转换。
CLion 配置方法
MISRA
引用
- MISRA(官网)
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/c_cpp_coding_guidelines
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!