ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ReactOS C/C++ 编码规范详解:从 CODING_STYLE.md 解读官方代码风格指南

2026/9/13 13:04:21 拓冰建站 浏览量
ReactOS C/C++ 编码规范详解:从 CODING_STYLE.md 解读官方代码风格指南 ReactOS C/C 编码规范详解从 CODING_STYLE.md 解读官方代码风格指南【免费下载链接】reactosA free Windows-compatible Operating System项目地址: https://gitcode.com/GitHub_Trending/re/reactos本文以 ReactOS 仓库根目录下的 CODING_STYLE.md 为主体完整解析该社区在 2013 年 10 月会议上共同确认的 C/C 编码风格指南文件头模板、缩进与行宽、运算符间距、换行、大括号、控制流、命名、注释以及NULL/TRUE/FALSE书写约定。读完后你将能够按照 ReactOS 官方标准编写新代码并正确处理既有代码重格式化这类提交场景。适用范围与边界哪些代码必须遵守CODING_STYLE.md开篇明确了规范的作用对象该指南仅适用于 C 和 C 源文件是 ReactOS 新代码的通用编码风格尽可能多的既有 ReactOS 代码应当转换到这一风格除非存在反对理由例如代码近期将被从头重写与其他代码源如 Wine保持同步的代码绝不能改写。仓库通过 media/doc/3rd Party Files.txt 和 media/doc/WINESYNC.txt 两个文件来跟踪哪些文件属于同步文件这两份清单都位于 media/doc 目录下。这一边界在实践中非常重要一个典型的对照例子是内核内存管理模块 ntoskrnl/mm/freelist.c它的文件头仍是旧式COPYRIGHT/PROJECT/FILE/PURPOSE/PROGRAMMERS格式说明存量代码仍在向新规范迁移而新提交的代码则必须直接采用下文描述的新式文件头。文件结构File Structure1. 新式文件头模板每个 ReactOS 源文件都应以如下的文件头开始/* * PROJECT: ReactOS Kernel * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Does cool things like Memory Management * COPYRIGHT: Copyright 2017 Arno Nymous abcmailaddress.com * Copyright 2017 Mike Blablabla mikeblabla.com */配套规则有四点LICENSE一行必须使用SPDX 许可证标识符如GPL-2.0-or-later目的是让许可证扫描类工具能够直接解析源文件如果你对某个文件做了重大贡献、并能为整个文件或其中一部分承担责任才应把自己加入COPYRIGHT段每个文件的COPYRIGHT列表不得超过 3 人旧式文件头中的FILE行应当删除新模板不再携带该字段。2. Doxygen 文档ReactOS 代码库使用 Doxygen 作为文档生成器因此函数需要编写符合规范的函数头注释。仓库根目录提供了 Doxyfile 配置文件文档中对函数注释细节的进一步说明指向了官方 Wiki 的 API Documentation 章节属外部资源此处仅作指引正文以本仓库内容为准。缩进与行宽Indentation and line width共 6 条规则逐条给出要点行宽最多 100 个字符任何行尾不得添加空格或制表符使用4 个空格缩进禁止使用 Tabswitch语句中case标签和case内部语句都要缩进。文档给出的正确写法switch (Condition) { case 1: DoSomething(); break; case 2: { DoMany(); ManyMore(); OtherThings(); break; } }而以下写法是错误的switch后无空格、case未缩进、缩进宽度不一致switch(Condition) { case 1: DoSomething(); break; case 2: DoMany(); ManyMore(); OtherThings(); break; }第 5 条函数调用放不进一行时参数按左括号对齐换行FunctionCall(arg1, arg2, arg3);第 6 条函数声明函数头必须按以下固定顺序排列各要素——作用域标识符 → 节放置 → 其他属性 → 返回类型 → 调用约定 → 函数名与参数static // scope identifier CODE_SEG(PAGE) // section placement // other attributes BOOLEAN // return type FASTCALL // calling convention IsOdd( _In_ UINT32 Number);这里的两个要素在 ReactOS SDK 中有真实的宏定义支撑可以从源码结构确认其存在与含义CODE_SEG定义在 sdk/include/ndk/section_attribs.h 中GCC/Clang 下展开为__attribute__((section(segment)))MSVC 下展开为__declspec(code_seg(segment))。把代码放进PAGE/NONPAGED等节是内核代码的硬性要求因此该宏出现在函数头第二行FASTCALL调用约定大量用于内核函数原型例如 sdk/include/ndk/exfuncs.h 中的多个Ex*函数声明均以FASTCALL修饰。间距规则Spacing文档给出 5 条间距规则全部配有正误对照一元运算符周围不加空格。对i;错i ;二元与三元运算符两侧加空格。对a b c;错abc;逗号与分号前面不加空格。对for (int i 0; i 5; i) DoSomething(); func1(a, b);错for (int i 0; i 5 ; i) DoSomething(); func1(a , b) ;控制语句与其括号之间加空格。对if (Condition)错if(Condition)函数名与其括号之间、括号与其内容之间不加空格。对func(a, b);错func (a, b);或func( a, b );换行规则Line breaking每条语句独占一行。正确示例x; y; if (Condition) DoSomething();错误示例把多条语句挤在一行、if与语句体同行x; y; if (Condition) DoSomething();大括号规则Braces大括号{和}必须各自独占一行即 Allman 风格这与内核代码中常见的 KR 风格明显不同单行控制语句可以用也可以不用大括号但带额外注释的单行控制语句是例外必须加大括号。文档Right示例集中展示了全部合法形态if (Condition) DoSomething(); if (Condition) { DoSomething(); } if (Condition) { // This is a comment DoSomething(); } if (A_Very || (Very Long || Condition) On_Many Lines) { DoSomething(); } if (Condition) DoSomething(); else DoSomethingElse(); if (Condition) { DoSomething(); } else { DoSomethingElse(); YetAnother(); }对应的Wrong反例则覆盖了四类常见违规if (Condition) {把左括号挂在行尾单行语句前放游离注释却未加大括号长条件换行后语句体直接跟在不完整的结构后else {括号挂尾。这些反例是评审代码时可以直接引用的检查基准。控制结构Control structures两条规则控制条件中不要使用反转逻辑。对if (i 1)错if (1 i)即不要把常量放在比较符左侧——这与部分项目防误写赋值的写法相反ReactOS 明确不采用该写法避免层层嵌套的树状结构偏好线性风格当goto能让代码更清晰时例如统一的清理/回滚路径应当使用它。文档给出的线性风格范例if (!func1()) return; i func2(); if (i 0) return; j func3(); if (j 1) return; ...反面是逐级包裹的多层if嵌套文档中给出了三层嵌套的错误示例此处从略其形态即先 if 再大括号再 if的金字塔结构。命名规则Naming变量和函数名一律首字母大写。为 Win32 开发时可以非强制使用匈牙利记法如果不使用匈牙利记法首字母也必须大写禁止 lowerCamelCase也不要用下划线作分隔符。对PLIST_ENTRY FirstEntry; VOID NTAPI IopDeleteIoCompletion(PVOID ObjectBody); PWSTR pwszTest;错PLIST_ENTRY first_entry; VOID NTAPI iop_delete_io_completion(PVOID objectBody); PWSTR pwsztest;避免对函数与变量名过度缩写能用描述性动词就用描述性动词布尔值变量在合适时以Is、Did等有意义的前缀开头对BOOLEAN IsValid; BOOLEAN DidSendData;错BOOLEAN Valid; BOOLEAN SentData;注释规则Commenting避免浪费行数的注释——能写成一行的注释不要拆成多行骨架对// This is a one-line comment /* This is a C-style comment */ // This is a comment over multiple lines. // We dont define any strict rules for it.错// // This comment wastes two lines //NULL、布尔值与字符串终止符空指针一律写作NULL。如果你的环境推荐使用其他空指针表示例如 C11 的nullptr可以使用但绝不能写0Win32/NT 风格的布尔值写作TRUE和FALSE仅当你确实在使用 C/C 的bool类型时才写作true和false终止 ANSI 或 OEM 字符串、或检查其终止符时使用ANSI_NULL若为 Unicode/Wide 字符串使用UNICODE_NULL。重格式化既有代码的注意事项文档给出了两条提交纪律是 ReactOS 贡献流程中可操作的要求绝不能在同一个提交里既完全重格式化一个文件又夹带功能改动——两者必须拆成独立的提交如果一个提交只包含格式修改必须在提交信息前缀中明确标注[FORMATTING]。这两条规则的价值在于纯格式提交不会污染代码考古git blame / 历史检索功能提交则保持最小 diff便于逐行审查。其他约定Other points文档还列出三条补充约定除非需要使用对应 API否则不要用LARGE_INTEGER/ULARGE_INTEGER改用INT64/UINT64头文件中使用#pragma once不再使用 guard 宏include guard。仓库内的 NDK 头文件也实际采用该做法例如 sdk/include/ndk/section_attribs.h 第 19 行即为#pragma once除非确有必要通常是 API 或导出符号不要为函数指定调用约定。尚待完成与有意留白的部分CODING_STYLE.md中有两个章节目前是占位状态反映文档仍在演进Using an automatic code style tool标注 TO BE ADDED即自动格式化工具的具体使用说明尚未写入Points deliberately left out讨论中提出过更多想法但未能达成共识因此明确不对这些点强制规定正文同样标注 TO BE ADDED。这意味着对于这两块内容当前仓库没有可依据的规则写代码时不应自行发明统一做法以社区后续修订为准。快速自检清单结合全文提交新 C/C 代码前可按以下清单核对检查项依据条款文件头含 PROJECT/LICENSE(SpDX)/PURPOSE/COPYRIGHT无 FILE 行COPYRIGHT ≤ 3 人File Structure行宽 ≤ 100 字符、无行尾空白、4 空格缩进、无 TabIndentation 1-3switch的 case 标签与内容均缩进Indentation 4长调用参数与左括号对齐Indentation 5函数声明顺序作用域 → CODE_SEG → 返回类型 → 调用约定Indentation 6控制语句与括号间有空格函数名与括号间无空格Spacing 4-5每条语句独占一行Line breaking大括号独占一行带注释的单行控制语句加大括号Braces无if (1 i)式反转比较用线性风格控制流Control structures标识符首字母大写布尔变量带 Is/Did 前缀Naming空指针写NULL而非0NT 布尔写TRUE/FALSENull, false and 0纯格式提交独立且以[FORMATTING]前缀Notes on reformatting以上各条规则均可在 CODING_STYLE.md 中找到原始表述与正误代码对照涉及CODE_SEG、FASTCALL等宏的实际定义可进一步查阅 sdk/include/ndk/section_attribs.h 与 sdk/include/ndk/exfuncs.h。【免费下载链接】reactosA free Windows-compatible Operating System项目地址: https://gitcode.com/GitHub_Trending/re/reactos创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考