Add a C++ style guide
Table of contents
Problem
When writing C++ code for Carbon, we want to keep all of our code consistent, easy to learn, and help avoid spending undue code review time arguing about the same core style and idiomatic issues.
Background
- C++ Coding Standards
- C++ Core Guidelines
- Chromium C++ style guide
- Google C++ Style Guide
- Joint Strike Fighter Air Vehicle C++ Coding Standards
- LLVM Coding Standards
- Mozilla C++ Style Guide
- Programming style
- The Elements of Programming Style
- WebKit Code Style Guidelines
Proposal
I propose to use the Google C++ style guide as a baseline, and then make minimal, focused additions and adjustments to it to suit the needs of Carbon.
Details
The Google C++ style guide is widely used even outside of Google. Both Mozilla and Chromium use it as their base style guide. It is both comprehensive and specific, providing a strong foundation with wide coverage.
However, there are a small number of places that seem worth adjusting. I propose to use the Google style guide as a baseline and then have a minimal, and focused list of changes and clarifications.
The most expensive cases are those where we actively diverge from this baseline. Doing this outside of mechanical formatting issues would require careful thought and justification that seems likely to have a higher cost than the benefit. I propose focusing only on specific places where there is a direct benefit to Carbon by diverging. The only place where I suggest this is the naming convention. The convention suggested by Google’s style guide is more complex than necessary, in part due to its desire to not invalidate a large historical codebase. That is not a concern for Carbon, and there is a specific advantage: using and learning how the proposed naming convention for Carbon itself works in practice. Thus, the proposal is to replace the naming conventions suggested by the Google style guide with those suggested for Carbon.
The remaining suggested modifications simply consist of selecting one of several allowed options in order to increase consistency and modernness. Many of the cases allowing multiple options only exist to retain consistency with an existing code base that isn’t a factor for Carbon. I suggest we take advantage of this to have a more consistent and modern style. See the proposed section for details.
Rationale
Some aspects of this proposal warrant specific rationale.
Alternatives considered
Different variations on the baseline of the Google C++ style guide
Use exceptions
Advantages:
- Better aligned with standard C++, Boost, and some other C++ communities.
Disadvantages:
- Significant performance problems, especially of data structures that need to provide strong exception safety guarantees.
- LLVM does not use exceptions and is not exception safe.
Format functions with one-per-line arguments and parameters
Note: this is likely a bikeshed that we should not invest significant time debating.
Advantages:
- Simpler for editors and authors of code to get correct.
- Minimizes diffs during refactorings.
- Regular horizontal rhythm (independent of name lengths) and no hard-to-spot additional parameters on the right, which for some subset of readers improves readability.
Disadvantages:
- A non-trivial change from Google’s style guide.
- Readability problems caused by bin packing of function parameters and arguments are typically better solved by factoring (either into variables or option structs) than a formatting change. We should not have interfaces that are hard to read due to their number of parameters.
- Increases vertical space of code, which for some subset of readers is expensive, and for them may outweigh any benefit of the regular horizontal rhythm.
Place *
and &
with the variable in pointer declarations
Note: this is likely a bikeshed that we should not invest significant time debating.
Advantages:
- This spacing matches the language grammar more closely than the alternative spacing.
- Declaration syntax parallels the usage syntax. Given
int *p;
, the type of*p
isint
. - Enables coherent declaration of multiple variables in a single declaration.
- However, even with this formatting these declarations are hard to read and should not be used.
Disadvantages:
- Many people think of the declaration structure as
<type> <identifier>;
and the*
is part of the type.- However, that intuitive understanding doesn’t generalize to a few different constructs in C++. For example: arrays and function pointers.
Place const
after the type
Note: this is likely a bikeshed that we should not invest significant time debating.
Advantages:
- Makes multiple layers of
const
alternating with pointers or references more obviously readable.- However, using type aliases to avoid multiple layers of
const
often provides even better readability.
- However, using type aliases to avoid multiple layers of
Disadvantages:
- For declarations without any pointer in the type,
const <type> <id>;
is much more conventional.- And most declarations are of this form.
Use the LLVM coding standards
Carbon will end up heavily using LLVM and Clang for its reference implementation. This will both involve interfacing with those APIs and heavily using libraries from those projects. We could adopt the LLVM coding standards to gain consistency with those APIs.
Advantages:
- Consistent coding style between Carbon code and any LLVM or Clang APIs used.
- If it eventually becomes desirable to contribute Carbon’s reference implementation to the LLVM project, it would avoid updating the code to adhere to the relevant coding standards.
Disadvantages:
- The LLVM coding standards are neither precise nor specific on a number of points. They leave a large number of issues to the judgement of code reviewers to stay consistent with the LLVM codebase. This isn’t practical for Carbon nor is it an efficient policy.
- LLVM and Clang don’t consistently follow the standards either, making it impossible to have complete consistency with them.
- Contributing the reference implementation to LLVM seems unlikely and necessarily at least a year away which minimizes any concerns around style matching.
- LLVM has not yet adopted C++17 due to existing users who still need C++14. However, Carbon has no such need to constrain its version of C++ and can effectively adopt and use more modern C++ versions.
Rationale
A common, established style guide will allow us to focus on the more important aspects of coding and code review. Once we’re familiar with the rules, their consistent application will result in a more readable codebase, and rules that can largely be automated by clang-format will result in a more efficient development process.
This particular ruleset attempts to align with our expected lexical rules for the Carbon language (for example, comment syntax and capitalization rules), which will also mean that we can use a largely consistent style between the aspects of the toolchain implemented in C++ and the aspects implemented in Carbon.