cpp-google-style
Skill0 starsChanged 9 days agoMITView on GitHub
Apply the Google C++ Style Guide (https://google.github.io/styleguide/cppguide.html) plus mandatory Doxygen comments on every class and function when writing, editing, or reviewing C++ code (.h, .hpp, .cc, .cpp). Use for any C++ work, and when asked to check/lint C++ code against the style guide.
In this repository28 other files it gives its agents.
- accessibility-auditSkill
- api-design-reviewSkill
- architecture-reviewSkill
- complexity-checkSkill
- concurrency-reviewSkill
- config-reviewSkill
- csharp-google-styleSkill
- dead-code-finderSkill
- dependency-auditSkill
- doc-comment-auditSkill
- error-handling-reviewSkill
- full-reviewSkill
- java-google-styleSkill
- logging-reviewSkill
- markdown-readme-google-styleSkill
- naming-reviewSkill
- owasp-security-reviewSkill
- performance-reviewSkill
- privacy-reviewSkill
- python-google-styleSkill
- regex-reviewSkill
- repo-hygieneSkill
- review-without-fixingSkill
- secrets-scanSkill
- shell-google-styleSkill
- sql-reviewSkill
- test-coverage-reviewSkill
- todo-auditSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 6 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
Put code in project-specific namespaces.
- Very specific: line 22
Never using namespace, inline namespaces, or declarations in std.
- Distinctive: line 25
Prefer namespaced nonmember functions over globals.
- Very specific: line 31
No virtual calls in constructors.
- Very specific: line 38
All data members private (constants excepted).
- Distinctive: line 40
Keep large method bodies out of the class definition.
- Distinctive: line 45
Do not require a reference parameter to outlive the call.
- Distinctive: line 46
Keep functions short (reconsider beyond about 40 lines).
- Distinctive: line 48
Default arguments only on non-virtual functions with always-identical defaults.
- Very specific: line 55
Avoid RTTI (typeid, dynamic_cast) outside tests.
- Distinctive: line 71
No C++20 modules. Coroutines only via approved libraries.
- Very specific: line 73
No nonstandard extensions (__attribute__, __builtin_*, #pragma, inline asm, VLAs, alloca(), a?:b) except via a project portability header.
- Very specific: line 90
Use // or /* */ consistently.
- Very specific: line 98
Every class, struct, enum, function, method, constructor, destructor, and template alias gets a Doxygen comment, including trivial …
- Very specific: line 99
Use / ... */ blocks (/// only for one-line member docs) with Javadoc-style tags:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Google C++ Style Guide + Doxygen
Source: https://google.github.io/styleguide/cppguide.html
Follow the rules below when writing or changing C++. When reviewing, report violations as file:line - rule - fix, grouped by section. In existing code that does not follow this guide, match the local conventions of the file unless the user asks for a migration. Follow the project's file extensions (.hpp/.cpp are fine) instead of forcing .h/.cc. For details not covered here, consult the source URL.
Header Files
- Pair each source file with a header (tests and tiny
main()files excepted). Headers are self-contained: guarded and including everything they need. - Guard format
<PROJECT>_<PATH>_<FILE>_H_(use_HPP_for.hpp) from the full path in the source tree. No#pragma once. - Include what you use; never rely on transitive includes. Prefer
#includeover forward declarations; never forward-declare entities you do not own. - Inline and template definitions live in the header; no
-inl.h. Define functions in headers only if short (about 10 lines), and make them ODR-safe (inline, template, or in-class). Put header-only implementation in aprivatesection or aninternalnamespace. - Include order, one blank line between groups, alphabetical within each: 1. related header, 2. C system headers, 3. C++ standard headers, 4. other libraries, 5. project headers.
- Project headers by path from the source root, no
./... Angle brackets only for standard/system/third-party headers.
Scoping
- Put code in project-specific namespaces; no indentation inside; comment closing braces of multi-line namespaces (
} // namespace foo). Prefernamespace a::b {for nesting. - Never
using namespace, inline namespaces, or declarations instd. No namespace aliases at header namespace scope (except ininternalnamespaces). - Implementation details go in namespaces whose name contains
internal. - In
.ccfiles give internal linkage to anything other files do not need (unnamed namespace, closing comment} // namespace, orstatic); never in headers. - Prefer namespaced nonmember functions over globals; no classes that only group static members.
- Declare variables in the narrowest scope, initialize at declaration; declare
if/while/forvariables inside the statement. - Static-storage objects must be trivially destructible; mark constants
constexpr/constinit; avoid dynamic initialization of non-local statics; no smart pointers as statics. Fallback:static const auto& x = *new T(...);. - Namespace/class-scope
thread_localmust beconstinit; prefer function-local.
Classes
- No virtual calls in constructors; avoid fallible constructors (use factory or
Init()). No exceptions. expliciton single-argument constructors and conversion operators (copy/move exempt;initializer_listconstructors may omit it).- Make copy/move support explicit in the public interface:
= defaultor= delete. Declare or delete both copy operations, both move operations. Omit only when obvious (passive structs, clearly non-copyable base). - Prevent slicing: base classes get protected constructors/destructors or a pure virtual. Avoid deriving from concrete classes.
structonly for passive data, all fields public, no invariants; otherwiseclass. Prefer a namedstructoverstd::pair/std::tuplewhen elements have meaning.- Composition over inheritance. Public inheritance only, for is-a. Mark non-base classes
final. Exactly one ofoverride/finalon overrides, no redundantvirtual. Avoid multiple implementation inheritance. - Operators: overload only when meaning is obvious, only on your own types, in the same namespace; non-member for non-modifying binary operators; define
operator==for equality; never overload&&,||,,, unary&; no user-defined literals. - All data members
private(constants excepted). - Declaration order:
public,protected,private(omit empty). Within each: types/aliases, static constants, factories, constructors/assignment, destructor, other functions, data members. - Keep large method bodies out of the class definition.
Functions
- Return values rather than output parameters; return by value, else reference; raw pointers only when null is meaningful.
- Inputs by value or
const&; non-optional outputs/in-out by non-const reference; optional by-value inputstd::optional; optional input reference asconst*; optional output as non-const pointer. Input parameters before output parameters. - Do not require a reference parameter to outlive the call.
- Keep functions short (reconsider beyond about 40 lines).
- Overload only when semantically identical; one umbrella comment for an overload set; prefer
std::string_viewoverconst std::string&/const char*overloads. - Default arguments only on non-virtual functions with always-identical defaults.
- Leading return types by default; trailing only when required or clearly clearer.
Other C++ Features
- Ownership: single fixed owner;
std::unique_ptrfor transfer;std::shared_ptronly with strong reason (prefershared_ptr<const T>). Neverauto_ptr. - Rvalue references only for move operations,
&&-qualified consuming methods, forwarding references withstd::forward, andFoo&&/const Foo&overload pairs. friendsparingly, defined in the same file as the class. No exceptions;noexceptonly when accurate (move constructors).- Avoid RTTI (
typeid,dynamic_cast) outside tests; prefer virtual methods or Visitor. - Casts: no C-style (except to
void);int64_t{x}for arithmetic,std::string(x)for class types,static_castfor sure up/down casts,const_castonly to remove const,reinterpret_castonly when necessary,std::bit_castfor punning. - Streams only for ad-hoc, local, human-readable I/O; no manipulators/format flags/
imbue(); prefer logging libraries andabsl::StrCat/StrFormat. Overload<<only for value types; useDebugString()for debugging. - Prefix
++i/--iunless the postfix value is used. constwherever accurate (const T¶ms,constmethods; allconstoperations thread-safe); noconston by-value parameters in declarations.constexprfor true constants,constinitfor guaranteed constant initialization,constevalfor compile-time-only; never to force inlining.- Integers:
intfor ordinary values (at least 32 bits);<stdint.h>types when size matters;int64_tfor values that may reach 2^31. Unsigned only for bit patterns/modular arithmetic, never to express non-negativity. Avoidshort,long,long long. - Floating point: only
floatanddouble; neverlong double. - Portability: no
printfformatting; addresses inuintptr_t; braces for 64-bit constants (uint64_t{3} << 48). - Macros: avoid; prefer inline functions, enums,
constexpr. If unavoidable: project-prefixed, define right before use and#undefright after, none in headers, no##name generation. nullptrfor pointers,'\0'for the null character. Prefersizeof(variable)oversizeof(type).autoonly when it makes code clearer or safer (obvious types, iterators, lambdas); keep explicit types that carry information; structured bindings for map elements; avoiddecltype(auto),autoparameters in non-lambda functions, and return-type deduction in public headers.- CTAD only for templates with an explicit deduction guide (all
stdtemplates qualify). - Designated initializers: C++20 form, in declaration order.
- Lambdas: prefer explicit captures if the lambda may escape;
[&]only when obviously shorter-lived than captures;[=]only for short lambdas, never implicitly capturingthis; no init-captures that introduce new names or shadow; init-captures for move-only variables are fine. - Templates: avoid metaprogramming (recursive instantiation, type lists, SFINAE, expression templates); hide it from user-facing headers.
- Concepts: sparingly, only where C++17 would have used a template; no new concepts in public headers; prefer standard concepts; use
requires(...), nottemplate<Concept T>orenable_if. - No C++20 modules. Coroutines only via approved libraries. No Boost unless the project uses it.
- Banned standard headers:
<ratio>,<cfenv>/<fenv.h>,<filesystem>. - No nonstandard extensions (
__attribute__,__builtin_*,#pragma, inline asm, VLAs,alloca(),a?:b) except via a project portability header. - Aliases:
usingovertypedef; public aliases only if clients should use them, with documented intent; local aliases fine in function bodies, private sections, internal namespaces,.ccfiles. - Switch:
defaultunless switching on an enum; unreachabledefaultis an error; annotate fall-through with[[fallthrough]];. - Inclusive language: no master/slave, blacklist/whitelist; use they/them for unspecified people, it/its for software.
Naming
Clear to a new reader, descriptiveness scaled to scope. Avoid unfamiliar abbreviations; never drop letters within words; capitalize abbreviations as words (StartRpc()).
- Files: lowercase with underscores (
my_class.cc,my_class_test.cc); do not reuse/usr/includenames; be specific. - Types (classes, structs, enums, aliases, type template parameters, concepts):
PascalCase. - Variables and parameters:
snake_case. Class data memberssnake_case_(trailing underscore); struct members without. - Constants (
constexpr/constwith static storage):kPascalCase. Enumerators likewise, neverENUM_NAME. - Functions:
PascalCase; trivial accessors/mutators may besnake_case(count(),set_count()). Names mirroring a standard entity may follow its convention (size(),empty()). - Namespaces:
snake_case, globally unique top level, neverstd/absl. - Template parameters: types like types, non-types like variables/constants;
Tandiare fine for simple cases. - Macros:
ALL_CAPS_WITH_UNDERSCORES, project-prefixed.
Comments
- Use
//or/* */consistently. Write complete sentences with correct punctuation. Explain why, not what; prefer clear names over comments that explain obscure ones. - Files: license boilerplate if the project requires it; describe the abstractions when a file declares several.
- Function definitions: explain tricky logic and the approach taken, not what the declaration comment already says.
- Variables: comment class members only when invariants, sentinel values, or lifetimes are not obvious. Document every global: what it is and why it must be global.
- Implementation: comment tricky or important blocks. For unclear call arguments prefer, in order: named constants, enums instead of
bool, option structs, named variables, finally/*param=*/comments. - TODO:
TODO(identifier): description(bug ID, name, or email).
Doxygen (mandatory; overrides Google's "skip trivial comments")
- Every class, struct, enum, function, method, constructor, destructor, and template alias gets a Doxygen comment, including trivial accessors, private/protected members, and
internalnamespaces. No class or function may be left without a comment. A missing Doxygen comment is a violation in reviews. - Use
/** ... */blocks (///only for one-line member docs) with Javadoc-style tags:@brieffirst: one sentence, third-person verb phrase ("Opens the file.").@tparamfor every template parameter,@paramfor every parameter (add[in],[out],[in,out]when direction is not obvious),@returnfor every non-void return value (state whatfalse/nullptr/error values mean).@note,@warning,@pre,@post,@see,@code ... @endcodewhere useful: lifetime of reference/pointer arguments, nullability, state changes, complexity, threading, invariants.- Overrides use
@copydoc Base::Methodor a short@brief; deleted/defaulted special members get a one-line@brief. - Each header starts with a
@file/@briefblock.
- Class comments explain what the class is for, when to use it, threading assumptions, and invariants; a short
@codeusage example is encouraged.
Formatting
- Max 80 columns (exceptions: unsplittable URLs/comments, includes, header guards, using-declarations). Spaces only, 2 per indent. UTF-8, non-ASCII rare. No trailing whitespace.
- Functions: return type on the name line; no space before
(;{at end of line after one space. Wrapped parameters align with the first one, or break after(with a 4-space indent. Unused parameter names omitted or commented (/*radians*/). Attributes before the return type. - Lambdas: format like functions;
[&x]without space. - Float literals: digits on both sides of the point,
fsuffix for float (1.0f,1248.0e6). - Calls and braced init lists: one line if it fits, else align with the first argument or break after
(with a 4-space indent; treat{like(. No spaces inside parentheses. if/for/while/switch: space after the keyword, none inside parentheses.} else {on one line. Braces required; omit only if the statement fits on one line (or two with a break after)), never forif ... elseordo ... while. Empty loop bodies{}orcontinue;, never a bare;.- Switch:
case 1:no space before the colon; braced cases ascase 0: {,break;inside the braces. - Pointers/references:
char* c;,const std::string& s;; no spaces around./->; no multi-declarations with pointer/reference variables. - Boolean expressions: wrap with operators at line ends; use
&&,||,!, neverand/or/not. return result;without parentheses. Initialization:=,(),{}all fine; braces prevent narrowing but preferinitializer_listconstructors.- Preprocessor directives start at column 0, even inside indented code.
- Class format:
public:/protected:/private:indented 1 space, members 2; blank line before each label except the first, none after. Base class on the same line:class Foo : public Bar {. - Constructor initializer lists: one line if it fits; otherwise break before the colon, indent 4 spaces, one member per line.
- Horizontal whitespace: two spaces before end-of-line comments; space before
{, none before;; spaces around assignment and most binary operators; unary operators unspaced (-5,++x);Foo() {}for empty,void Reset() { x_ = 0; }otherwise; no spaces in template brackets or casts (static_cast<char*>(x)). - Vertical whitespace: sparingly; none at the start or end of a block; separate logical chunks like paragraphs.
Exceptions
- Existing non-conformant code: match local conventions; ask the code owner when unsure.
- Windows code: no Hungarian notation, stay close to standard C++ types, no
#pragma once, wrap__declspecin macros, MSVC warning level 3+ with warnings as errors.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

