扉页

版本:

2024/02/18

原作者:
Benjy Weinberger
Craig Silverstein
Gregory Eitzmann
Mark Mentovai
Tashana Landray
翻译:
项目主页:

译者前言

Google 经常会发布一些开源项目, 意味着会接受来自其他代码贡献者的代码. 但是如果代码贡献者的编程风格与 Google 的不一致, 会给代码阅读者和其他代码提交者造成不小的困扰. Google 因此发布了这份自己的编程风格指南, 使所有提交代码的人都能获知 Google 的编程风格.

翻译初衷:

规则的作用就是避免混乱. 但规则本身一定要权威, 有说服力, 并且是理性的. 我们所见过的大部分编程规范, 其内容或不够严谨, 或阐述过于简单, 或带有一定的武断性.

Google 保持其一贯的严谨精神, 5 万汉字的指南涉及广泛, 论证严密. 我们翻译该系列指南的主因也正是其严谨性. 严谨意味着指南的价值不仅仅局限于它罗列出的规范, 更具参考意义的是它为了列出规范而做的谨慎权衡过程.

指南不仅列出你要怎么做, 还告诉你为什么要这么做, 哪些情况下可以不这么做, 以及如何权衡其利弊. 其他团队未必要完全遵照指南亦步亦趋, 如前面所说, 这份指南是 Google 根据自身实际情况打造的, 适用于其主导的开源项目. 其他团队可以参照该指南, 或从中汲取灵感, 建立适合自身实际情况的规范.

我们在翻译的过程中, 收获颇多. 希望本系列指南中文版对你同样能有所帮助.

我们翻译时也是尽力保持严谨, 但水平所限, bug 在所难免. 有任何意见或建议, 可与我们取得联系.

中文版和英文版一样, 使用 Artistic License/GPL 开源许可.

中文版修订历史:

  • 2015-08 : 热心的清华大学同学 @lilinsanity 完善了「类」章节以及其它一些小章节。至此,对 Google CPP Style Guide 4.45 的翻译正式竣工。

  • 2015-07 4.45 : acgtyrant 为了学习 C++ 的规范,顺便重新翻译了本 C++ 风格指南,特别是 C++11 的全新内容。排版大幅度优化,翻译措辞更地道,添加了新译者笔记。Google 总部 C++ 工程师 innocentim, 清华大学不愿意透露姓名的唐马儒先生,大阪大学大学院情报科学研究科计算机科学专攻博士 farseerfc 和其它 Arch Linux 中文社区众帮了译者不少忙,谢谢他们。因为 C++ Primer 尚未完全入门,暂时没有翻译「类」章节和其它一些小章节。

  • 2009-06 3.133 : YuleFox 的 1.0 版已经相当完善, 但原版在近一年的时间里, 其规范也发生了一些变化.

    Yang.Y 与 YuleFox 一拍即合, 以项目的形式来延续中文版 : Google 开源项目风格指南 - 中文版项目.

    主要变化是同步到 3.133 最新英文版本, 做部分勘误和改善可读性方面的修改, 并改进排版效果. Yang.Y 重新翻修, YuleFox 做后续评审.

  • 2008-07 1.0 : 出自 YuleFox 的 Blog, 很多地方摘录的也是该版本.

以下是正文.

背景

C++ 是谷歌的开源项目所采用的主要编程语言之一. C++ 程序员都知道, 该语言有很多强大的特性 (feature), 但强大之处也伴随着复杂性, 让代码容易出错, 难以阅读、维护.

本指南的目标是详述 C++ 的注意事项来控制复杂性. 这些规则会在保持代码易于管理的同时, 不影响程序员高效地使用 C++ 的语言特性.

风格 (style, 亦称作可读性 (readability)) 是用于管理 C++ 代码的惯例. “风格” 这一术语略有不准确, 因为这些惯例并非仅仅囊括代码格式.

谷歌主导的大部分开源项目遵守本指南的要求.

注意: 本指南并非 C++ 教程, 我们假定读者已经非常熟悉 C++.

本指南的目标

为什么编写这份文档?

我们认为该指南应该实现以下核心目标. 这些目标是每条规则背后的基本 依据 . 我们希望公开这些想法, 作为讨论的基础, 让广大社区了解每条规则和特定决策背后的来由. 在理解规则所服务的目标以后, 所有人都应该清楚某条规则在哪些情况下可以忽略 (有些规则可以忽略), 以及改变规则时需要提供怎样的论据和替代品.

我们认为风格指南当前的目标如下:

风格规则应该有影响力

一条风格规则应该具备足够大的好处, 以至于值得所有工程师铭记. 所谓好处是相对于当前代码库的状态而言的, 所以即使某一习惯十分恶劣, 如果人们很少使用, 那么禁止这一习惯的好处依然很小. 这样可以解释为什么我们没有写下某些规则. 例如, goto 语句违背了许多原则, 但是现在已经很少出现, 所以风格指南不会讨论它.

为读者优化, 而非为作者优化

我们的代码库 (以及其中的每个组件) 应该会存在很长时间. 因此, 我们读代码的时间比写代码的时间更长. 我们明确地选择优化平均水平的软件工程师阅读、维护和调试代码的体验, 而非编写代码的舒适度. “为读者留下线索” 是这一理念的一个方面. 如果代码中有特殊的情况 (例如指针所有权转移), 在此处给读者留下的文字提示很有价值 (在代码中使用 std::unique_ptr 就明确地表达了所有权转移).

和现有代码保持一致

我们让代码库的风格保持整体一致, 就能聚焦在其他 (更有价值的) 问题上. 一致性也会帮助自动化: 那些格式化代码或者调整 #include 顺序的工具, 只能在你的代码符合预期时才能正常工作. 很多时候, 那些用于 “保持一致” 的规则本质上就是 “任选其一并停止内耗”; 在这些问题上, 争论的成本超过了提供自由度的价值. 不过, 一致性原则也有局限性. 在没有清晰的技术性论据和长远方向时, 这才是很好的打破平局的方式. 这一原则适合局部使用 (一个文件内, 或者一组关联性强的接口). 不应该为了一致性而采用旧风格, 忽视新风格的好处. 应该考虑到代码库会随时间推移而过渡到新风格.

恰当时与广大 C++ 社区保持一致

与其他组织保持一致性是有价值的, 这和我们保持内部一致性的原因一样. 如果 C++ 标准中的特性解决了某个问题, 或者某一范式被广泛采用, 这就是采纳它们的依据. 不过, 有时标准的特性和范式有缺陷, 或者在设计上没有考虑我们代码库的需求. 此时 (正如下文所描述的) 应该限制或者禁止这些标准特性. 有时, 相较于 C++ 标准库, 我们偏向于自研库或某些第三方库. 一般这是因为我们所选择的库具有优越性, 或者迁移到标准库的价值不值得那些工作量.

避免使用奇特或危险的语法结构

有些 C++ 的特性比表面上更加奇特或危险. 风格指南中的一些限制就是为了防止掉入这些陷阱. 你需要达到很高的标准才能豁免这些限制, 因为忽略这些规则就很可能直接引起程序错误.

避免使用那些正常水平的 C++ 程序员认为棘手或难以维护的语法结构

有些 C++ 特性会给代码带来复杂性, 因此通常不适合使用. 在用途广泛的代码中, 我们可以接受更巧妙的语法结构. 这是因为复杂的实现方式所带来的收益会被众多使用者放大, 而且在编写新代码时, 也不需要重新解读这些复杂的语法. 如有疑问, 可以请求项目主管豁免这些规则. 这对我们的代码库至关重要, 因为代码负责人和团队成员会变化: 即使所有现在修改这段代码的人都理解代码, 几年后人们就不一定还能理解了.

需要注意我们的规模

我们有上亿行代码和成千上万的工程师, 因此一位工程师的失误或者投机取巧的行为会成为很多人的负担. 举例来说, 一定要避免污染全局命名空间 (global namespace): 如果所有人都往全局命名空间里塞东西, 就很难避免上亿行代码之间的符号冲突 (name collision), 也难以修复冲突.

在必要时为优化让路

即使性能优化的手段会和此文档的其他理念冲突, 有时这些手段也是必要且恰当的.

此文档的目的是提供最大程度的指导和合理限制. 和往常一样, 你应该追随常理和正常审美. 这里我们特指整个谷歌 C++ 社区所建立的规范, 而不是你个人或者所在团队的偏好. 应该对巧妙或奇特的语法结构保持怀疑和犹豫的态度: 并不是 “法无禁止即可为”. 运用你的判断力. 如有疑惑, 请不要犹豫, 随时向项目主管咨询意见.

C++ 版本

目前代码的目标版本是 C++20, 所以不应该使用 C++23 的特性. 本指南的 C++ 目标版本会随时间 (激进地) 升级.

禁止使用非标准扩展.

在使用 C++17 和 C++20 的特性之前, 需要权衡其他环境的可移植性.