# Add a C++ style guide

<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

[Pull request](https://github.com/carbon-language/carbon-lang/pull/113)

<!-- toc -->

## Table of contents

-   [Problem](#problem)
-   [Background](#background)
-   [Proposal](#proposal)
-   [Details](#details)
    -   [Rationale](#rationale)
-   [Alternatives considered](#alternatives-considered)
    -   [Different variations on the baseline of the Google C++ style guide](#different-variations-on-the-baseline-of-the-google-c-style-guide)
        -   [Use exceptions](#use-exceptions)
        -   [Format functions with one-per-line arguments and parameters](#format-functions-with-one-per-line-arguments-and-parameters)
        -   [Place `*` and `&` with the variable in pointer declarations](#place--and--with-the-variable-in-pointer-declarations)
        -   [Place `const` after the type](#place-const-after-the-type)
    -   [Use the LLVM coding standards](#use-the-llvm-coding-standards)
-   [Rationale](#rationale-1)

<!-- tocstop -->

## 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](https://dl.acm.org/doi/book/10.5555/1036281)
-   [C++ Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-   [Chromium C++ style guide](https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md)
-   [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
-   [Joint Strike Fighter Air Vehicle C++ Coding Standards](https://stroustrup.com/JSF-AV-rules.pdf)
-   [LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html)
-   [Mozilla C++ Style Guide](https://firefox-source-docs.mozilla.org/code-quality/coding-style/coding_style_cpp.html)
-   [Programming style](https://en.wikipedia.org/wiki/Programming_style)
-   [The Elements of Programming Style](https://dl.acm.org/doi/book/10.5555/578130)
-   [WebKit Code Style Guidelines](https://webkit.org/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](/docs/project/cpp_style_guide.md)
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](/docs/project/cpp_style_guide.md#carbon-local-guidance) 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` is `int`.
-   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.

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.
