Google C++ Style Guide

based on https://google.github.io/styleguide/cppguide.html

mmass_sern
ยทOct 20, 2025ยท40 views
# Google C++ Style Guide

Based on https://google.github.io/styleguide/cppguide.html

## C++ Version

Target C++20. No C++23. No non-standard extensions.

## Headers

Self-contained. End in `.h`. Include what you use.

Guard format: `<PROJECT>_<PATH>_<FILE>_H_`

```cpp
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif  // FOO_BAR_BAZ_H_
```

Include order:
1. Related header
2. C system headers (angle brackets, `.h` extension)
3. C++ standard library (no extension)
4. Other libraries
5. Project headers

Blank line between groups. Alphabetical within.

No forward declarations. Include the header.

Short inline functions OK in headers (~10 lines). Longer ones go in `.cc`.

## Scoping

Use namespaces. Never `using namespace`. Never declare in `std`.

Terminate with `}  // namespace foo`.

Unnamed namespace or `static` for file-local stuff. Never in headers.

Declare variables in narrowest scope. Initialize at declaration.

```cpp
while (const char* p = strchr(str, '/')) str = p + 1;
```

Static/global: trivially destructible only. Use `constexpr` or `constinit`.

`thread_local` at class/namespace scope: must be `constinit`.

## Classes

Data members `private`. Always. Trailing underscore: `member_`.

Structs: passive data only, all public, no trailing underscore.

Explicitly declare or `= delete` copy/move ops.

```cpp
class Copyable {
 public:
  Copyable(const Copyable&) = default;
  Copyable& operator=(const Copyable&) = default;
};

class MoveOnly {
 public:
  MoveOnly(MoveOnly&&) = default;
  MoveOnly& operator=(MoveOnly&&) = default;
  MoveOnly(const MoveOnly&) = delete;
  MoveOnly& operator=(const MoveOnly&) = delete;
};
```

Prefer composition over inheritance. `public` inheritance only.

Use `override` or `final`. Never `virtual` on overrides.

No virtual calls in constructors. No failing init in constructors.

Mark single-arg constructors `explicit`. Mark conversion operators `explicit`.

Declaration order: `public`, then `protected`, then `private`. 1-space indent for access specifiers.

Within each section:
1. Types and aliases
2. Static constants
3. Factory functions
4. Constructors/assignment
5. Destructor
6. Methods
7. Data members

## Functions

Return values, not output parameters. Return by value or reference, not raw pointer unless nullable.

Input params: values or `const&`. Output params: references (non-null) or pointers (nullable).

Keep functions short. ~40 lines max.

Overload only when semantics identical.

Default args: non-virtual only, constants only.

Use trailing return type only when required (lambdas, complex templates).

## Ownership

`std::unique_ptr` for ownership transfer.

`std::shared_ptr` only when actually shared. Prefer `shared_ptr<const Foo>`.

Never `std::auto_ptr`.

## Other C++ Features

Rvalue refs: only for move ops, `&&`-qualified methods, perfect forwarding.

Friends: OK within reason. Define in same file.

No exceptions.

`noexcept`: use when useful for performance. Unconditional if exceptions disabled.

No RTTI except tests. No `typeid`, no `dynamic_cast` decision trees.

No C-style casts. Use `static_cast`, `const_cast`, `reinterpret_cast`, `std::bit_cast`.

Prefer `++i` over `i++`.

Use `const` on APIs. Methods: `const` unless they mutate state.

`constexpr` for true constants. Don't overcomplicate to enable it.

Integer types: use `int` for small values. Use `<stdint.h>` types (`int64_t`, etc.) for specific sizes. Avoid unsigned except for bit patterns.

No `long double`. Use `float` and `double` only.

Avoid macros. If needed: `ALL_CAPS`, project prefix, `#undef` after use.

`nullptr` for pointers. `'\0'` for null char.

`sizeof(varname)` over `sizeof(type)`.

`auto`: use only when it makes code clearer. Not to avoid typing.

No CTAD unless template opts in with explicit deduction guides.

Lambdas: prefer explicit captures. `[&]` only for short-lived lambdas. No `[=]` with `this`.

```cpp
[&foo] { Frobnicate(foo); }  // Good - explicit
[&] { Frobnicate(foo); }     // Bad if lambda escapes
```

No template metaprogramming abuse. Keep it simple.

Use `requires(Concept<T>)` syntax over `template<Concept T>`.

No C++20 modules. No coroutines except approved libraries.

Boost: only approved subset (call_traits, compressed_pair, graph, iterator, polygon/voronoi, bimap, math, multi_index, heap, flat containers, intrusive, sort, preprocessor).

No `<ratio>`, `<cfenv>`, `<filesystem>`.

Switch: always `default` case. Use `[[fallthrough]]` for fall-through.

## Naming

Descriptive. Proportional to scope. Minimize abbreviations.

```
ClassName           PascalCase
ConceptName         PascalCase
FunctionName        PascalCase
variable_name       snake_case
class_member_       snake_case with trailing _
struct_member       snake_case, no trailing _
kConstantName       k + PascalCase
MACRO_NAME          ALL_CAPS
namespace_name      snake_case
kEnumValue          k + PascalCase (not ENUM_VALUE)
```

File names: lowercase, `_` or `-`. Use `.cc` and `.h`.

Accessors/mutators may be snake_case: `int count()`, `void set_count(int)`.

## Comments

`//` preferred. Be consistent.

File: license boilerplate, then optional overview.

Class: what it's for, how to use it, thread safety.

Function declaration: what it does, not how. Document ownership, nullability, side effects.

Function definition: tricky implementation details.

Variables: clarify sentinel values, non-obvious usage.

TODO format:
```cpp
// TODO: bug 12345678 - Remove after Q4 2025.
// TODO(username): Fix this.
```

## Format

80 char line limit. Exceptions: URLs, include paths, guard macros.

2-space indent. No tabs.

```cpp
ReturnType ClassName::FunctionName(Type par1, Type par2) {
  DoSomething();
}

// Long params
ReturnType LongClassName::ReallyLongFunctionName(
    Type par1,  // 4 space indent
    Type par2,
    Type par3) {
  DoSomething();  // 2 space indent
}
```

Braces on same line. Always use braces for loops/conditionals (exception: single-line OK).

```cpp
if (condition) {
  DoThing();
} else {
  DoOther();
}

if (x == kFoo) return new Foo();  // OK - single line
```

No spaces inside parens. Space after `if`, `for`, `while`, `switch`.

Pointer/reference: `char* c`, not `char *c`. No space before `*` or `&`.

Namespace contents not indented.

```cpp
namespace foo {

void Bar();

}  // namespace foo
```

Class format:
```cpp
class MyClass : public Base {
 public:      // 1 space indent
  MyClass();  // 2 space indent

 private:
  int member_;
};
```

Constructor init lists:
```cpp
MyClass::MyClass(int var)
    : member_(var),
      other_(var + 1) {
  DoSomething();
}
```

Lambda:
```cpp
auto fn = [&x](int n) -> int { return x + n; };
```

Preincrement: `++i`, not `i++`.

Vertical whitespace: sparingly. No blank lines at start/end of blocks.

Full guide: https://google.github.io/styleguide/cppguide.html

Comments

No comments yet

Be the first to share your thoughts!