/cpp-coding-standards
C++ coding standards based on the C++ Core Guidelines (isocpp.github.io). Use when writing, reviewing, or refactoring C++ code to enforce modern, safe, and idiomatic practices.
$ npx -y skills add affaan-m/ECC --skill cpp-coding-standards --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/cpp-coding-standards
Context preview
The summary Claude sees to decide when to auto-load this skill.
C++ coding standards based on the C++ Core Guidelines (isocpp.github.io). Use when writing, reviewing, or refactoring C++ code to enforce modern, safe, and idiomatic practices.
SKILL.md
cpp-coding-standards.SKILL.mdname: cpp-coding-standards
description: C++ coding standards based on the C++ Core Guidelines (isocpp.github.io). Use when writing, reviewing, or refactoring C++ code to enforce modern, safe, and idiomatic practices.
metadata:
origin: ECC
C++ Coding Standards (C++ Core Guidelines)
Comprehensive coding standards for modern C++ (C++17/20/23) derived from the [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). Enforces type safety, resource safety, immutability, and clarity.
When to Use
- Writing new C++ code (classes, functions, templates)
- Reviewing or refactoring existing C++ code
- Making architectural decisions in C++ projects
- Enforcing consistent style across a C++ codebase
- Choosing between language features (e.g., `enum` vs `enum class`, raw pointer vs smart pointer)
When NOT to Use
- Non-C++ projects
- Legacy C codebases that cannot adopt modern C++ features
- Embedded/bare-metal contexts where specific guidelines conflict with hardware constraints (adapt selectively)
Cross-Cutting Principles
These themes recur across the entire guidelines and form the foundation:
1. **RAII everywhere** (P.8, R.1, E.6, CP.20): Bind resource lifetime to object lifetime 2. **Immutability by default** (P.10, Con.1-5, ES.25): Start with `const`/`constexpr`; mutability is the exception 3. **Type safety** (P.4, I.4, ES.46-49, Enum.3): Use the type system to prevent errors at compile time 4. **Express intent** (P.3, F.1, NL.1-2, T.10): Names, types, and concepts should communicate purpose 5. **Minimize complexity** (F.2-3, ES.5, Per.4-5): Simple code is correct code 6. **Value semantics over pointer semantics** (C.10, R.3-5, F.20, CP.31): Prefer returning by value and scoped objects
Philosophy & Interfaces (P.*, I.*)
Key Rules
| Rule | Summary | |------|---------| | **P.1** | Express ideas directly in code | | **P.3** | Express intent | | **P.4** | Ideally, a program should be statically type safe | | **P.5** | Prefer compile-time checking to run-time checking | | **P.8** | Don't leak any resources | | **P.10** | Prefer immutable data to mutable data | | **I.1** | Make interfaces explicit | | **I.2** | Avoid non-const global variables | | **I.4** | Make interfaces precisely and strongly typed | | **I.11** | Never transfer ownership by a raw pointer or reference | | **I.23** | Keep the number of function arguments low |
DO
// P.10 + I.4: Immutable, strongly typed interface
struct Temperature {
double kelvin;
};
Temperature boil(const Temperature& water);DON'T
// Weak interface: unclear ownership, unclear units
double boil(double* temp);
// Non-const global variable
int g_counter = 0; // I.2 violation
Functions (F.*)
Key Rules
| Rule | Summary | |------|---------| | **F.1** | Package meaningful operations as carefully named functions | | **F.2** | A function should perform a single logical operation | | **F.3** | Keep functions short and simple | | **F.4** | If a function might be evaluated at compile time, declare it `constexpr` | | **F.6** | If your function must not throw, declare it `noexcept` | | **F.8** | Prefer pure functions | | **F.16** | For "in" parameters, pass cheaply-copied types by value and others by `const&` | | **F.20** | For "out" values, prefer return values to output parameters | | **F.21** | To return multiple "out" values, prefer returning a struct | | **F.43** | Never return a pointer or reference to a local object |
Parameter Passing
// F.16: Cheap types by value, others by const&
void print(int x); // cheap: by value
void analyze(const std::string& data); // expensive: by const&
void transform(std::string s); // sink: by value (will move)
// F.20 + F.21: Return values, not output parameters
struct ParseResult {
std::string token;
int position;
};
ParseResult parse(std::string_view input); // GOOD: return struct
// BAD: output parameters
void parse(std::string_view input,
std::string& token, int& pos); // avoid thisPure Functions and constexpr
// F.4 + F.8: Pure, constexpr where possible
constexpr int factorial(int n) noexcept {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
static_assert(factorial(5) == 120);Anti-Patterns
- Returning `T&&` from functions (F.45)
- Using `va_arg` / C-style variadics (F.55)
- Capturing by reference in lambdas passed to other threads (F.53)
- Returning `const T` which inhibits move semantics (F.49)
Classes & Class Hierarchies (C.*)
Key Rules
| Rule | Summary | |------|---------| | **C.2** | Use `class` if invariant exists; `struct` if data members vary independently | | **C.9** | Minimize exposure of members | | **C.20** | If you can avoid defining default operations, do (Rule of Zero) | | **C.21** | If you define or `=delete` any copy/move/destructor, handle them all (Rule of Five) | | **C.35** | Base class destructor: public virtual or protected non-virtual | | **C.41** | A constructor should create a fully initialized object | | **C.46** | Declare single-argument constructors `explicit` | | **C.67** | A polymorphic class should suppress public copy/move | | **C.128** | Virtual functions: specify exactly one of `virtual`, `override`, or `final` |
Rule of Zero
// C.20: Let the compiler generate special members
struct Employee {
std::string name;
std::string department;
int id;
// No destructor, copy/move constructors, or assignment operators needed
};Rule of Five
// C.21: If you must manage a resource, define all five
class Buffer {
public:
explicit Buffer(std::size_t size)
: data_(std::make_unique<char[]>(size)), size_(size) {}
~Buffer() = default;
Buffer(const Buffer& other)
: data_(std::make_unique<char[]>(other.size_)), size_(other.size_) {
std::copy_n(other.data_.get(), size_, data_.get());
}
Buffer&Read more
name: cpp-coding-standards description: C++ coding standards based on the C++ Core Guidelines (isocpp.github.io). Use when writing, reviewing, or refactoring C++ code to enforce modern, safe, and idiomatic practices. metadata: origin: ECC
C++ Coding Standards (C++ Core Guidelines)
Comprehensive coding standards for modern C++ (C++17/20/23) derived from the [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). Enforces type safety, resource safety, immutability, and clarity.
When to Use
- Writing new C++ code (classes, functions, templates)
- Reviewing or refactoring existing C++ code
- Making architectural decisions in C++ projects
- Enforcing consistent style across a C++ codebase
- Choosing between language features (e.g., `enum` vs `enum class`, raw pointer vs smart pointer)
When NOT to Use
- Non-C++ projects
- Legacy C codebases that cannot adopt modern C++ features
- Embedded/bare-metal contexts where specific guidelines conflict with hardware constraints (adapt selectively)
Cross-Cutting Principles
These themes recur across the entire guidelines and form the foundation:
1. **RAII everywhere** (P.8, R.1, E.6, CP.20): Bind resource lifetime to object lifetime 2. **Immutability by default** (P.10, Con.1-5, ES.25): Start with `const`/`constexpr`; mutability is the exception 3. **Type safety** (P.4, I.4, ES.46-49, Enum.3): Use the type system to prevent errors at compile time 4. **Express intent** (P.3, F.1, NL.1-2, T.10): Names, types, and concepts should communicate purpose 5. **Minimize complexity** (F.2-3, ES.5, Per.4-5): Simple code is correct code 6. **Value semantics over pointer semantics** (C.10, R.3-5, F.20, CP.31): Prefer returning by value and scoped objects
Philosophy & Interfaces (P.*, I.*)
Key Rules
| Rule | Summary | |------|---------| | **P.1** | Express ideas directly in code | | **P.3** | Express intent | | **P.4** | Ideally, a program should be statically type safe | | **P.5** | Prefer compile-time checking to run-time checking | | **P.8** | Don't leak any resources | | **P.10** | Prefer immutable data to mutable data | | **I.1** | Make interfaces explicit | | **I.2** | Avoid non-const global variables | | **I.4** | Make interfaces precisely and strongly typed | | **I.11** | Never transfer ownership by a raw pointer or reference | | **I.23** | Keep the number of function arguments low |
DO
// P.10 + I.4: Immutable, strongly typed interface
struct Temperature {
double kelvin;
};
Temperature boil(const Temperature& water);DON'T
// Weak interface: unclear ownership, unclear units double boil(double* temp); // Non-const global variable int g_counter = 0; // I.2 violation
Functions (F.*)
Key Rules
| Rule | Summary | |------|---------| | **F.1** | Package meaningful operations as carefully named functions | | **F.2** | A function should perform a single logical operation | | **F.3** | Keep functions short and simple | | **F.4** | If a function might be evaluated at compile time, declare it `constexpr` | | **F.6** | If your function must not throw, declare it `noexcept` | | **F.8** | Prefer pure functions | | **F.16** | For "in" parameters, pass cheaply-copied types by value and others by `const&` | | **F.20** | For "out" values, prefer return values to output parameters | | **F.21** | To return multiple "out" values, prefer returning a struct | | **F.43** | Never return a pointer or reference to a local object |
Parameter Passing
// F.16: Cheap types by value, others by const&
void print(int x); // cheap: by value
void analyze(const std::string& data); // expensive: by const&
void transform(std::string s); // sink: by value (will move)
// F.20 + F.21: Return values, not output parameters
struct ParseResult {
std::string token;
int position;
};
ParseResult parse(std::string_view input); // GOOD: return struct
// BAD: output parameters
void parse(std::string_view input,
std::string& token, int& pos); // avoid thisPure Functions and constexpr
// F.4 + F.8: Pure, constexpr where possible
constexpr int factorial(int n) noexcept {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
static_assert(factorial(5) == 120);Anti-Patterns
- Returning `T&&` from functions (F.45)
- Using `va_arg` / C-style variadics (F.55)
- Capturing by reference in lambdas passed to other threads (F.53)
- Returning `const T` which inhibits move semantics (F.49)
Classes & Class Hierarchies (C.*)
Key Rules
| Rule | Summary | |------|---------| | **C.2** | Use `class` if invariant exists; `struct` if data members vary independently | | **C.9** | Minimize exposure of members | | **C.20** | If you can avoid defining default operations, do (Rule of Zero) | | **C.21** | If you define or `=delete` any copy/move/destructor, handle them all (Rule of Five) | | **C.35** | Base class destructor: public virtual or protected non-virtual | | **C.41** | A constructor should create a fully initialized object | | **C.46** | Declare single-argument constructors `explicit` | | **C.67** | A polymorphic class should suppress public copy/move | | **C.128** | Virtual functions: specify exactly one of `virtual`, `override`, or `final` |
Rule of Zero
// C.20: Let the compiler generate special members
struct Employee {
std::string name;
std::string department;
int id;
// No destructor, copy/move constructors, or assignment operators needed
};Rule of Five
// C.21: If you must manage a resource, define all five
class Buffer {
public:
explicit Buffer(std::size_t size)
: data_(std::make_unique<char[]>(size)), size_(size) {}
~Buffer() = default;
Buffer(const Buffer& other)
: data_(std::make_unique<char[]>(other.size_)), size_(other.size_) {
std::copy_n(other.data_.get(), size_, data_.get());
}
Buffer&Your agent can write code, but ECC gives it a coordinated engineering system and toolbox: it plans before it builds, verifies changes with tests, reviews its own work from a fresh context, remembers what matters, and turns repeated wins into reusable skills
Repo: affaan-m/ECC
Other skills on ecc.
- /everything-claude-code
Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.
Open skill - /accessibility
Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA
Open skill - /agent-architecture-audit
Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for
Open skill - /agent-eval
Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics
Open skill - /agent-harness-construction
Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates.
Open skill - /agent-introspection-debugging
Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports.
Open skill

