Carbon 语言 C++ 风格指南:以 Google 风格为基线的最小化增补方案(提案 p000113 解读)

发布时间:2026/9/11 11:46:46

Carbon 语言 C++ 风格指南:以 Google 风格为基线的最小化增补方案(提案 p000113 解读) Carbon 语言 C 风格指南以 Google 风格为基线的最小化增补方案提案 p000113 解读【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang导读本文围绕 Carbon 语言仓库中的提案 p000113-add-a-c-style-guide.md 展开解读 Carbon 项目为何选择 Google C 风格指南作为基线、又针对自身需求做了哪些最小化聚焦的增补与调整并对照仓库中最终落地的 C 风格指南、.clang-format 与 .clang-tidy 配置说明这些规则如何被工具化执行。读者读完后将完整掌握 Carbon 的 C 命名约定、语法格式化偏好、初始化与传址规则、auto使用策略以及它在 LLVM/Clang 生态下的库选择与异常处理立场可作为向 Carbon 提交 C 代码或理解其工具链源码风格的直接参考。提案背景为什么 Carbon 需要一份 C 风格指南Carbon 语言的参考实现toolchain主体由 C 编写仓库中toolchain/目录下的 driver、lex、parse、check、lower、sem_ir 等模块均为 C 源码。提案在 Problem 一节指出三个核心诉求一致性保持所有 C 代码风格统一易学性让新人容易上手、规则边界清晰降低评审成本避免在代码评审中反复争论同样的风格与惯用法问题。提案在 Background 一节系统调研了当时业界主流的多份 C 编码规范包括 C Coding Standards、C Core Guidelines、Chromium C style guide、Google C Style Guide、JSF-AVJoint Strike Fighter Air Vehicle C Coding Standards、LLVM Coding Standards、Mozilla C Style Guide、WebKit Code Style Guidelines 等。这为选取一个成熟基线而非从零发明的决策提供了充分背景。核心提案Google 风格基线 Carbon 本地化增补提案的立场非常明确以 Google C style guide 为基线做最小、聚焦的增补与调整。理由包括Google 风格指南在 Google 之外同样被广泛使用Mozilla 与 Chromium 均以其为基线它既全面又具体覆盖面广、基础扎实大多数情况下主动偏离基线的成本高于收益尤其是在机械格式化之外的领域偏离需要审慎论证。在此基础上Carbon 只选择能带来直接收益的少数分歧点命名约定Google 风格的命名约定因历史代码库兼容需求而偏复杂Carbon 没有历史包袱且希望通过实践检验 Carbon 语言自身的命名方案。因此提案以 docs/project/cpp_style_guide.md 中的 Carbon 命名规则替换 Google 建议的命名约定。多个允许选项中选定其一Google 指南中不少允许多种写法的选项其存在只是为了兼容既有代码库。Carbon 可以借此收紧规则获得更一致、更现代的样式。详见风格指南中的 Carbon-local guidance 一节。Carbon 本地化指导细则落地解读提案最终在 docs/project/cpp_style_guide.md 中落地为可操作的规则。以下逐节展开。命名规则贴近 Carbon 语言自身的命名方案Carbon 的 C 代码刻意向 Carbon 语言的命名约定靠拢以便在实践中熟悉这套约定恰巧它与 Google 风格相当接近主要作用是简化。已知编译期常量使用UpperCamelCase引用专有名词包括命名空间、类型名、函数、成员函数下述例外除外、模板参数、constexpr变量、枚举值等。虚成员函数必须使用UpperCamelCase虚函数与非虚函数在调用点应无差别可见因为是否为虚函数属于内部实现细节命名不应随其改动。成员函数可退化为snake_case的条件仅当其行为仅为返回数据成员的引用或set_方法赋值或其行为含性能特征对假设其为简单访问器的调用者来说毫不意外时。其余一切名称使用snake_case包括函数参数、非常量的局部变量与成员变量私有成员变量需加尾缀_。缩写与首字母缩略词的写法一般遵循 Google 风格如Api而非API例外是LLVM与IR保持大写。工具链缩写表常用缩写维护在 toolchain/docs/idioms.md 的abbreviations used in the code (AKA Carbon abbreviation decoder ring)小节例如Instinstruction、Exprexpression、Decldeclaration、SemIRsemantics intermediate representation等注释中一般不用缩写。这些命名规则在.clang-tidy中被显式配置为readability-identifier-naming.*检查如ClassCase: CamelCase、VariableCase: lower_case、ClassMemberCase: lower_case等即通过 clang-tidy 自动强制。变量命名_id后缀与类型消歧风格指南给出典型实践ID 类型变量通常加_id后缀必要时用完整类型名消歧。例如同一实体存在ClassId、InstId、TypeId时可命名为class_id、class_inst_id、class_type_id一个Inst可叫class_inst。这一约定与 toolchain/docs/idioms.md 中的 Index types 一节呼应IndexBase/IdBase是int32_t的小型包装toolchain/base/index_base.h_id后缀表明变量对应某个IdBase数组形式的 ID 集合用_block后缀或复数表示如param_refs。文件命名文件、目录、构建系统规则一律snake_case并避免使用-源文件统一使用.cpp扩展名开源社区最常见的写法也与不加标点的 C书写习惯一致。仓库中common/、toolchain/下的 C 实现均遵循此规则例如 common/check.h、toolchain/check/check.cpp。语法与格式化细则风格指南针对每个选项都合理、只需选一个保持一致的细节给出了明确选择并尽可能用clang-format强制执行一律使用尾返回类型语法- ReturnType包括- void以与 Carbon 语法保持一致指针*紧贴类型TypeName* variable_name一次只声明一个变量多变量声明需要重复类型的一部分易读性差外层const写在类型之前const int N 42;用using类型别名而非typedef禁止用using引入std、llvm、clang等命名空间的非限定查找如using std::vector;理由是为了获得更清晰的诊断并避免 ADL 引起的歧义例外是std::swap这类有意借助 ADL 调用的函数写法为{ using std::swap; swap(thing1, thing2); }构造函数一律explicit除非有明确理由支持隐式或{}初始化条件、switch、循环语句一律加大括号即使主体只有一条语句switch中case标签后按需加花括号建立作用域除空循环体外左花括号后立即换行内部链接优先用static而非匿名命名空间static最小化读者感知内部链接所需的上下文类与枚举仍须用匿名命名空间测试代码例外——应放在被测代码命名空间之下的匿名命名空间中访问控制针对.cpp文件中的 test fixture使用public而非protected这是由misc-non-private-member-variables-in-classestidy 检查所驱动的。行注释为 Carbon 注释语法自举试吃风格指南要求只用//行注释且独占一行例外是参数名注释、命名空间收尾注释等结构性注释尤其禁止把对某行代码的注释追加到该行行尾int bad 42; // Dont comment here. // Instead comment here. int good 42; // Closing namespace comments are structural, and both okay and expected. } // namespace MyNamespace这样做的三重收益为 Carbon 规划的注释语法吃自己的狗粮形成单一一致的放置规则对自动化重构更具韧性——重构常使代码变长、单行跨多行导致行尾注释无处安放而独立成行的前置注释在重构中仍不易混淆。初始化语法按能否编译分层的规则初始化规则的依据是什么能编译与 Abseil Tip #88 略有差异直接以目标值或直接指定该值的花括号初始化器初始化时用赋值语法聚合初始化优先用花括号结构体、std::pair、初始化列表等。结构体尽量用指定初始化器{.a 1}但 pair/tuple 不用仅在必须编译时才带类型名WizType{.a 1}——这与 Carbon 代码中结构体/元组的写法类似。对定义了构造函数的类型避免花括号初始化但llvm::SmallVectorint v {0, 1};这类初始化列表、std::pair、std::tuple除外永远不要对auto用花括号列表auto a {0, 1}是被禁止的其余多数情况优先括号初始化FooType foo(10);不带的花括号初始化BarType bar{10}作为兜底仅在其他构造函数语法无法编译时使用。传递地址引用优先指针用于两种情况向函数传递对象地址时除非以下情形之一否则一律使用引用参数可选用指针并文档化其可能为空地址被捕获且必须活得比调用表达式更久用指针并文档化其非空除非同时可选。存储非持有的成员地址时同样优先指针例如风格指南给出的示例class Bar { public: // foo must not be null. explicit Bar(Foo* foo) : foo_(foo) {} private: Foo* foo_; };auto的使用策略多数局部变量在类型可推断时使用auto但基本类型如bool、int例外。auto并非强制像SemIR::InstId这类较短类型名有时仍会显式写出——当类型比较晦涩、无法靠变量名说明时显式命名类型是有帮助的。函数参数一般显式写出类型lambda 参数在有益时可使用auto。这与 toolchain/docs/idioms.md 中 ValueStore 的用法建议一致从ValueStore取返回值时常依赖存储类型名隐含返回类型而使用auto。可复制与可移动类型类型应具备值语义尽量同时支持移动与拷贝无法拷贝的类型也应尽量支持移动若支持移动移动应尽可能高效。静态与全局变量一律constexpr无论文件、类还是函数作用域全局和静态变量都应声明为constexpr。仓库中这类模式的落地示例可参见 toolchain/docs/idioms.md 的 Defining constants usable in constexpr contexts 一节如类内静态常量配合static constexpr auto ComputeMyTable()计算器、以及toolchain/lex/lex.cpp中的IsIdStartByteTable全局常量表。基础库与数据类型工具链优先 LLVM工具链代码中优先使用 LLVM 库与数据结构而非标准 C 版本原因有二LLVM 容器针对无异常处理、无安全约束的编译器等高性能场景做过显著优化可以减少与 LLVM/Clang API 对接时的词汇类型摩擦。同时不得向可能成为编译器或运行时组成部分的代码引入其他第三方库依赖——编译器与运行库有独特的许可约束项目希望这些层的所有传递依赖都处于 LLVM 许可与 Carbon 项目整体一致之下。这也解释了为何提案在备选方案中否定了 LLVM 编码标准却仍深度拥抱 LLVM 库。迭代算法优先风格指南明确选择迭代而非递归算法并用 clang-tidy 辅助强制。原因在于 Carbon 预期被用于压力测试编译器的代码库API 复杂交互、代码生成器产生的重复结构等。Clang 靠近栈上限时启动线程的做法有性能开销且依赖开发者正确识别潜在递归因此 Carbon 选择迭代方案以获得性能与稳健性。仓库中common/下的array_stack.h、growing_range.h等数据结构正是为迭代式实现提供支撑的基础设施。工具化执行.clang-format与.clang-tidy风格指南的落地文档强调尽可能用工具强制执行减少作者与评审者的负担。仓库根目录的两个配置文件就是这一理念的直接产物。.clang-format格式化基线.clang-format 以BasedOnStyle: Google为基线再做 Carbon 本地化收紧PointerAlignment: Left——指针*紧贴类型对应指南*靠类型AllowShortBlocksOnASingleLine: false、AllowShortIfStatementsOnASingleLine: Never、AllowShortLoopsOnASingleLine: false、InsertBraces: true——强制单行块与大括号QualifierOrder: [inline, static, friend, constexpr, const, volatile, restrict, type]、QualifierAlignment: Custom——统一限定符顺序IfMacros/StatementMacros/Macros——为CARBON_DEFINE_RAW_ENUM_CLASS、CARBON_KIND_SWITCH、CARBON_ASSIGN_OR_RETURN、CARBON_KIND等宏提供格式化支持其中CARBON_ASSIGN_OR_RETURN(x)x让 clang-format 能看穿包含变量声明的宏。.clang-tidy静态检查收紧.clang-tidy 默认启用bugprone-*、google-*、misc-*、modernize-*、performance-*、readability-*六大类检查并设置WarningsAsErrors: *配合bazel build --configclang-tidy使用。同时按风格决策显式关闭了一批与项目选择冲突的检查例如-misc-use-anonymous-namespace、-readability-static-definition-in-anonymous-namespace——对应内部链接优先static-modernize-use-designated-initializers——对应仅对结构体使用指定初始化器-modernize-avoid-c-arrays、-performance-enum-size、-readability-magic-numbers等按工程成本评估后关闭。CheckOptions 中还直接编码了命名与格式化决策readability-identifier-naming.*Case系列类型/结构体/联合体/模板参数/typedef/命名空间/类常量一律CamelCase成员变量/参数/普通变量一律lower_caseNamespaceIgnoredRegexp: ^(clang|llvm)$允许为前置声明重新打开 LLVM/Clang 命名空间misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: true——与test fixture 用 public的决策配套modernize-use-trailing-return-type.TransformLambdas: none——与lambda 不必写返回类型一致。备选方案分析提案中的权衡提案在 Alternatives considered 一节记录了被否定的方案及其理由这些权衡最终沉淀为风格指南的立场。在 Google 基线之上做不同变体使用异常exceptions被否决。虽然更贴近标准 C、Boost 等社区但需要强异常安全保证的数据结构有显著性能问题且 LLVM 本身不使用异常、不异常安全。该立场也被 toolchain/docs/idioms.md 的 C 方言一节延续——工具链不使用异常、虚基类与 RTTI并与common/check.h中CARBON_CHECK/CARBON_DCHECK/CARBON_FATAL这类显式检查宏相配合。函数参数每行一个被判定为大概率不值得投入时间争论的 bikeshed。优点是编辑与作者不易写错、重构时 diff 最小、水平节奏规律缺点是偏离 Google 风格较大且参数过多导致的可读性问题更适合用分解提取变量或 option struct解决而非靠格式化。*与靠变量同样被标注为 bikeshed。优点是更贴近语言文法、声明与使用语法平行int *p;中*p类型为int、支持多变量声明缺点是多数人习惯把*视为类型的一部分——但这一直觉无法推广到数组和函数指针等结构。const后置bikeshed。优点是多层const与指针/引用交替时更易读但用类型别名避免多层const往往更佳缺点是无指针声明中const type id;更传统且这类声明占多数。采用 LLVM 编码标准提案明确否定了直接采用 LLVM Coding StandardsLLVM 规范在多处不够精确、具体把大量问题留给评审者对照既有代码库自行判断对 Carbon 不切实际且 LLVM/Clang 自身并未始终一致地遵循其标准向 LLVM 项目贡献参考实现的设想可能性低且至少一年以上风格匹配的顾虑被最小化LLVM 当时尚未采用 C17受限于仍需 C14 的既有用户而 Carbon 无此约束可以采纳更现代的 C 版本。为什么最终要这份规则Rationale 与后续影响提案的 Rationale 一节总结了最终收益聚焦更重要的事一份共同且成熟的风格指南让开发者与评审者把精力放在更重要的编码与评审问题上一致性带来可读性熟悉规则后一致的应用使代码库更易读可自动化能被 clang-format 自动化的规则带来更高效的开发流程——这一点已由根目录的 .clang-format 与 .clang-tidy 兑现与 Carbon 语言词法规则对齐例如注释语法与大小写规则使工具链中 C 与 Carbon 两部分代码可以使用大体一致的风格——C 的尾返回类型、UpperCamelCase/snake_case划分、{.a 1}指定初始化器都与 docs/design 中 Carbon 语言的语法方向呼应也与此后语言设计文档的 设计风格指南 形成配套体系。从提案到落地p000113 为 Carbon 工具链的 C 代码确立了Google 基线 最小化 Carbon 本地化增补的风格框架开发者若想为仓库贡献 C 代码直接阅读 C 风格指南并以 .clang-format 与 .clang-tidy 作为可执行约束即可快速对齐。【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/11 11:46:46

基于eBPF的零插桩全链路追踪:DeepFlow(deer-flow)实战解析

1. 从零认识deer-flow:它到底解决了什么问题 做后端开发或者运维的同学,多多少少都经历过这种场景:线上服务出问题了,用户反馈接口特别慢,你打开监控面板一看,CPU、内存、磁盘这些基础指标全部正常&#xf…

2026/9/11 11:41:46

deer-flow实战:可视化编排打造高效自动化工作流

1. 项目概述:deer-flow 是什么,能解决什么问题1.1 从"搬数据"到"跑流程",deer-flow 到底改变了什么先说说我为什么会对 deer-flow 这个项目这么上心。做了十多年后端开发和系统集成,我最烦的就是一类活儿&…

2026/9/11 11:41:46

零设计基础也能做App宣传图:Canva免费流程全拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/11 12:51:54

AIGC检测系统下的学术论文四维降重技术解析

1. 项目背景与核心痛点解析2023年学术圈最震撼的事件莫过于知网正式上线AIGC检测系统,这套系统与传统的文字重复率检测形成双重绞杀。我在高校任教的朋友透露,去年毕业季某985高校使用该系统初检,38%的论文被标记"AIGC高风险"&…

2026/9/11 12:51:54

AI Agent基础设施搭建实战:模型网关、向量库与MCP选型指南

做AI Agent这件事,我踩过最大的坑不是模型不会说话,而是地基没打好就急着盖楼。最近我们在LCODER实战系列里推进“问数项目智能体搭建”,目标很直接:让业务同学用大白话问一句“上个月华东区销售额同比变化怎么样”,Ag…

2026/9/11 12:51:54

视频技能增强系统:Skill RAG 实战指南

1. 项目概述:这不是一个“调API”的玩具,而是一套可落地的视频技能增强系统最近在 GitHub 上刷到一个叫deepseek-v4-flash-vision的开源项目,标题里带“flash”,不是营销话术——它真把多模态视频理解的推理延迟压到了工程可用级别…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码