You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
C++ 代码规范
1. 文件与编码
- 源文件使用
.cpp 后缀,头文件使用 .h 后缀。
- 文件名全部使用小写字母,多个单词之间使用下划线连接。
- 文件名应准确表达文件内容,且不得与系统头文件或 C++ 标准库头文件同名。
- 同一项目必须统一使用 UTF-8 编码。
- 删除行尾空格,避免产生无效的版本控制差异。
2. 命名
- 项目内应选定并统一命名风格,不得在同一作用域或模块中混用多种风格。
- 命名应清晰、准确、有明确含义;使用完整单词或公认缩写,避免单字符、无意义数字和容易误解的标识符。
- 命名中使用特殊约定或缩写时,应在注释中说明。
- 命名空间使用全小写字母,多个单词之间使用下划线连接,并应与项目名和目录结构对应。
- 类、结构体、枚举和类型别名使用大驼峰命名法。
- 函数使用项目统一的小驼峰或大驼峰命名法,并应使用准确的动宾词组描述其功能。
- 局部变量和普通变量使用项目统一的小驼峰或下划线命名法。
- 私有成员变量在名称末尾加下划线。
- 全局变量以
g_ 为前缀;除非确有必要,不得使用全局变量。
- 常量、宏和枚举值全部使用大写字母,多个单词之间使用下划线连接。
- 具有互斥或相反含义的变量、函数应使用语义明确的反义词组命名。
- 避免定义以下划线开头和结尾的标识符,编译开关和头文件保护等特殊场景除外。
- 应统一规划接口变量、结构、函数和常量的命名,避免编译或链接冲突。
- 不得让局部变量与全局变量同名。
3. 排版与格式
- 使用 4 个空格缩进,不使用 Tab 对齐。
- 一行只写一条语句。
- 代码行长度原则上不超过 100 个字符;包含完整 URL 或命令的注释可例外。
- 长语句、长表达式和过长的函数参数应换行;换行后保持适当缩进和清晰对齐。
- 长表达式应在低优先级运算符处换行;布尔表达式换行时,逻辑运算符置于行尾。
- 函数、类、结构体、枚举及控制语句的左、右大括号应各占一行,并与所属语句左对齐。
if、else、for、while、switch 等控制语句必须使用大括号;else 必须另起一行。
switch 必须包含 default 分支;每个 case 应使用代码块并显式结束处理流程。
- 空循环体必须使用空代码块或
continue 表达,不得仅使用分号。
- 预处理指令必须从行首开始,不得缩进。
public、protected、private 的声明顺序应为 public、protected、private。
- 命名空间内部不额外增加缩进层级。
- 函数定义之间最多保留两行空行;函数体和代码块的首尾不得保留空行。
- 相对独立的代码块之间可使用空行分隔,但不得使用无意义的空白。
- 对等二元运算符前后应保留空格;成员访问运算符
.、-> 前后以及一元运算符与操作数之间不得留空格。
if、for、while、switch 与左圆括号之间保留一个空格;函数调用的左圆括号后和右圆括号前不得留空格。
- 函数调用参数优先写在同一行;无法容纳时按第一个参数对齐或每行一个参数。
- 指针和引用声明中,
*、& 应与类型或变量名之一紧邻,同一文件内必须保持一致。
- 构造函数初始化列表可与函数声明同一行;换行时按 4 个空格缩进并保持对齐。
- 模板尖括号内不得添加多余空格。
4. 注释
- 优先通过清晰的架构、逻辑和命名提高可读性,仅在必要时添加注释。
- 注释应简洁、准确、无歧义,说明代码难以直接表达的意图、约束、风险或实现原因,不得简单重复代码含义。
- 修改代码时必须同步更新相关注释。
- 同一类注释必须采用统一风格;单行注释使用
//,多行注释使用 /* */。
- 需要生成接口文档,或接口契约无法从名称和类型直接理解时,使用统一的 Doxygen 风格注释。
- 文件头、类注释和函数注释不是强制项;仅在职责、使用限制或风险不直观时添加。
- 简单构造函数、析构函数、访问器、显而易见的私有辅助函数和简单数据成员不写注释。
- 对外复杂接口应说明关键参数约束、返回值、错误情况和使用限制。
- 函数实现处仅对关键实现细节、复杂逻辑或性能决策进行注释。
- 无法通过名称表达用途或存在特殊逻辑的数据成员、全局变量和常量必须添加注释。
- 临时方案、已知缺陷或后续优化项使用统一的
TODO(责任人): 描述 格式标记。
5. 数据与表达式
- 严禁将未初始化的变量作为右值使用。
- 应明确公共或全局数据的含义、作用、取值范围及相互关系;传递数据时必须防止非法值和越界。
- 数据结构成员数量应适中;成员过多时,应按职责拆分为子结构或独立类型。
- 跨 CPU 或分布式通信的数据结构必须考虑字节序、位域、字节对齐和数据布局。
- 不得直接使用难以理解的字面量;具有业务或物理意义的数值应定义为具名常量或枚举值。
- 应使用括号明确复杂表达式的计算顺序,不得依赖不易识别的运算符优先级。
- 避免使用难懂的技巧性代码;技巧不能替代可读性和可维护性。
6. 函数与模块
- 函数必须职责单一、功能明确,并精确实现设计要求。
- 函数规模原则上不超过 200 行;过长函数应按职责拆分。
- 不得设计职责过多或用途不明确的通用函数。
- 函数应具有可预测行为:相同输入和相同外部状态下应产生一致结果。
- 函数参数应尽量精简;未使用参数必须从接口中移除,避免使用
bool 控制参数。
- 接口函数必须明确参数合法性检查的责任方;未约定时由调用方负责。
- 函数必须校验其负责的参数输入及非参数输入(如文件、外部状态、共享数据)的有效性。
- 不得将函数参数直接作为工作变量修改;需要修改时应使用局部变量。
- 必须完整处理被调用函数的错误返回值。
- 函数返回值应清晰表达执行结果和错误状态;调用提供返回值的函数时应使用其返回值。
- 不得依赖隐式或不必要的强制类型转换作为函数返回值或调用参数。
- 函数调用点应易于理解,避免隐藏副作用和不必要的默认类型转换。
- 重复代码应提取为职责明确的函数;仅被单一上层函数调用且功能过小、不明确的函数可合并到上层函数。
- 降低模块和函数之间的耦合,提高函数独立性、可读性、效率和可维护性。
- 函数应保持高扇入、合理扇出,扇出原则上小于 7。
- 减少函数内部和函数之间的递归调用;使用递归前应评估终止条件、栈空间和性能。
- 多任务环境中的函数应具备可重入性;访问共享全局资源时必须使用适当的同步保护。
- 禁止在构造函数和析构函数中调用虚函数。
7. 宏与预处理
- C++ 中应优先使用
const、constexpr、enum、模板或 inline 函数替代宏。
- 必须使用宏时,宏名使用全大写加下划线命名法。
- 函数式宏的参数和整体表达式必须使用完整括号保护。
- 多语句宏必须使用
do { ... } while (0) 封装。
- 宏参数不得包含可能产生副作用的表达式。
8. 可读性与可测试性
- 关系紧密的代码应相邻放置;无关语句不得混入同一函数或代码块。
- 项目或产品内必须统一调试开关和调试输出函数。
- 调试信息格式必须统一,且至少包含模块名或源文件名及行号。
- 编码时应同步识别高风险业务规则并设计对应测试点;不要求为简单访问器和无分支转发函数重复编写测试,测试代码应可独立构建和运行。
- 集成测试或系统联调前必须准备测试环境、测试项目和测试用例,并持续优化测试用例。
- 应合理使用断言尽早发现不符合预期的软件状态。