State-of-the-art C and C++ engineering rules (2026 baseline) that Claude applies when writing or auditing C/C++. Covers modern idioms (RAII, value semantics, smart pointers, C++23), memory safety (lifetimes, bounds, sanitizers, hardening flags), undefined behavior, security (SEI CERT C/C++, MISRA, integer/buffer/format-string, injection), concurrency (C/C++ memory model, atomics, data races), build/tooling/CI (CMake, clang-tidy, cppcheck, ASan/UBSan/TSan, vcpkg/Conan, supply chain), and perfo...
Scanned 9/1/2026
Install to Claude Code
npx -y skills add martinholovsky/SOTA-skills --skill sota-c-cpp --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Sota C Cpp?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/martinholovsky-sota-c-cpp)More formats (shields.io, HTML) on the badges page.
---
name: sota-c-cpp
description: >-
State-of-the-art C and C++ engineering rules (2026 baseline) that Claude
applies when writing or auditing C/C++. Covers modern idioms (RAII, value
semantics, smart pointers, C++23), memory safety (lifetimes, bounds,
sanitizers, hardening flags), undefined behavior, security (SEI CERT C/C++,
MISRA, integer/buffer/format-string, injection), concurrency (C/C++ memory
model, atomics, data races), build/tooling/CI (CMake, clang-tidy, cppcheck,
ASan/UBSan/TSan, vcpkg/Conan, supply chain), and performance. Trigger keywords
- C, C++, cpp, RAII, smart pointer, unique_ptr, shared_ptr, undefined
behavior, UB, buffer overflow, use-after-free, double-free, sanitizer, ASan,
UBSan, TSan, valgrind, CMake, clang-tidy, clang-format, cppcheck, MISRA, CERT
C, memory safety, std::thread, atomics, std::move. Use for BOTH building
C/C++ libraries/systems and reviewing or auditing them.
---
# SOTA C & C++ (2026)
Expert-level rules for producing and auditing production C and C++. C and C++
are *memory-unsafe by default*: the compiler will not stop you from reading
freed memory, overrunning a buffer, or invoking undefined behavior (UB) that
the optimizer then weaponizes. These rules exist to claw back the safety the
language doesn't give you — through RAII, the type system, sanitizers, hardened
build flags, and disciplined review. Baseline: C++23 (ISO/IEC 14882:2024) and
C17/C23; flag where a control needs a newer toolchain. C++26 is feature-complete
(DIS ballot 2026) — contracts, reflection, erroneous behavior for uninitialized
reads, and a standardized hardened standard library; the last is usable today
via libc++/libstdc++ hardening flags (`rules/02`). Every rule states the
*why*; every rules file ends with an audit checklist of grep/clang-tidy/
sanitizer patterns.
## Purpose
Two consumers, one source of truth:
- **BUILD mode** — generating new C/C++: follow the rules as defaults, not
suggestions. Prefer C++ with RAII over raw C idioms unless the target is C.
Deviate only with a comment justifying it.
- **AUDIT mode** — reviewing existing C/C++: hunt violations using the audit
checklists, classify by severity, report in the finding format below. Memory-
safety and UB findings are presumed exploitable until proven otherwise.
## BUILD mode
1. Before writing, read the rules files relevant to the task (see index). A
parser handling untrusted bytes needs `02`, `03`, `04`; a threaded service
needs `05`.
2. Apply the **top-10 non-negotiables** (below) unconditionally.
3. New projects: CMake (≥3.20) with `-Wall -Wextra -Wpedantic -Werror`, the
[OpenSSF hardening flags](https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html)
(`rules/04`), a debug build wired to ASan+UBSan, clang-tidy + clang-format
configs, and CI running all of it from day one (`rules/06`).
4. Prefer the standard library and RAII types over hand-rolled
allocation/ownership. Every `new`/`malloc`/`fopen`/`mutex.lock()` should be
owned by a destructor (`unique_ptr`, container, `lock_guard`), not a manual
matching call you can forget on an early return or exception.
5. Treat warnings as errors. A clean `-Wall -Wextra` build is the floor, not
the goal — also run a static analyzer and the sanitizers (`rules/06`).
6. When you must use a sharp tool (raw pointer arithmetic, `reinterpret_cast`,
`unsafe` C interop, manual lifetime), leave a `// NOTE(sota):` comment
explaining the invariant you're upholding so auditors don't flag it blind.
## AUDIT mode
Work through each relevant rules file's audit checklist against the target.
Run the listed grep/clang-tidy/sanitizer commands; confirm each hit manually
(greps are recall-oriented). Where feasible, build with `-fsanitize=address,
undefined` and run the test suite — a sanitizer abort is ground truth.
### Severity conventions
| Severity | Meaning | Examples |
|---|---|---|
| **CRITICAL** | Exploitable memory corruption or guaranteed UB on reachable input | Heap/stack buffer overflow on attacker data, use-after-free, double-free, OOB write, format-string with user-controlled fmt, `system()` with interpolated input, data race on a pointer |
| **HIGH** | Likely corruption, crash, or security weakness | Unchecked `malloc`/`new` size from input, integer overflow feeding an allocation or index, missing bounds check, `strcpy`/`sprintf`/`gets`, TOCTOU on a path, missing RAII so a leak/UB occurs on the exception path |
| **MEDIUM** | Correctness/maintainability hazard, latent bug | Raw owning pointers, manual `new`/`delete` pairs, C-style casts, narrowing conversions, `memcpy` where a typed copy fits, missing `override`/`= delete`, signed/unsigned comparison |
| **LOW** | Idiom/perf debt, works but wrong shape | Pass-by-value of large objects, needless copies instead of `std::move`, `using namespace std` in headers, macros where `constexpr`/`inline` fits |
| **INFO** | Style/doc/hygiene | clang-format drift, naming, missing `[[nodiscard]]`, include hygiene |
### Finding format
```
[SEVERITY] file.cpp:LINE — short title
Rule: rules/NN-name.md § section
Evidence: the offending line(s), verbatim
Impact: one sentence — what corrupts/leaks/races, under what input
Fix: concrete replacement code or action
Effort: trivial | small | medium | large
```
Group findings by severity, CRITICAL first. End with: counts per severity, the
three highest-leverage fixes, and which checklists/sanitizers were run.
## Rules index
| File | Read this when... |
|---|---|
| `rules/01-idioms.md` | Writing/reviewing any C++: RAII and the rule of zero/five, ownership with `unique_ptr`/`shared_ptr`, value semantics and move, `const`/`constexpr`, references vs pointers, casts, `enum class`, error handling (exceptions vs `std::expected` vs error codes), **in-band sentinels (absence encoded as `-1`/`0`/`""`)** incl. **`EOF` in a `char` — broken only where `char` is unsigned**, C-vs-C++ idiom choices |
| `rules/02-memory-safety.md` | Anything touching pointers, buffers, lifetimes, or allocation: bounds, use-after-free/return, dangling references and views (`string_view`/`span`), iterator invalidation, ownership discipline, sanitizers (ASan/MSan), `_FORTIFY_SOURCE`/`_GLIBCXX_ASSERTIONS` |
| `rules/03-undefined-behavior.md` | Reasoning about UB and the optimizer: integer overflow, strict aliasing, uninitialized reads, null/misaligned access, signed shifts, data races as UB, `unsigned` arithmetic, UBSan, why "it worked in debug" proves nothing |
| `rules/04-security.md` | Any input crossing a trust boundary: CERT C/C++ + MISRA, banned functions (`gets`/`strcpy`/`sprintf`/`system`), integer-overflow-to-allocation, format strings, path traversal/TOCTOU, command injection, deserialization/parsers, CSPRNG, the OpenSSF hardening flag set |
| `rules/05-concurrency.md` | Anything with threads, atomics, or shared state: the C++ memory model, data races, `std::atomic` and memory orders, `mutex`/`lock_guard`/`scoped_lock`, deadlock ordering, condition variables, `std::jthread`/stop tokens, TSan |
| `rules/06-build-tooling-ci.md` | Setting up or auditing builds/CI: CMake hygiene, warning flags, clang-tidy/clang-format, static analysis (clang-analyzer, cppcheck, Coverity), sanitizer CI matrix, fuzzing (libFuzzer/OSS-Fuzz), dependencies and supply chain (vcpkg/Conan, pinning, SBOM). **Test *strategy* lives in `sota-testing`; this file owns C/C++ build/test mechanics.** |
| `rules/07-performance.md` | Latency/throughput/memory work: profiling (perf, VTune, Callgrind), allocation reduction and custom allocators, move/copy elision, cache locality and data-oriented layout, `<algorithm>` over hand loops, LTO/PGO, micro-benchmarking pitfalls |
## Top-10 non-negotiables
1. **Every resource is owned by a destructor (RAII).** No `new`/`delete` or
`malloc`/`free` pairs you have to match by hand; no bare owning pointers.
Use `unique_ptr`, containers, `lock_guard`/`scoped_lock`, RAII wrappers.
A leak or UB on the exception/early-return path is the default failure mode
of manual cleanup. (`rules/01`, `rules/02`)
2. **No buffer touches memory it doesn't own.** Bounds-check every index/
length derived from input; use `std::span`/`std::string`/containers and
`.at()` or explicit checks, never raw pointer + length you assume. Overflow
on attacker input is CRITICAL. (`rules/02`)
3. **No use-after-free / dangling.** A pointer, reference, iterator,
`string_view`, or `span` must not outlive its storage. Never return a
reference/view to a local or to a temporary. (`rules/02`)
4. **Undefined behavior is a bug even if it "works".** Signed integer
overflow, strict-aliasing violations, uninitialized reads, OOB, data races
are UB the optimizer may exploit. Build with UBSan; treat any UBSan
diagnostic as CRITICAL/HIGH. (`rules/03`)
5. **Integers feeding an allocation, index, or `memcpy` size are
overflow-checked and the right signedness.** Validate ranges before use;
prefer unsigned for sizes, check for wrap. Overflow-to-undersize-alloc is a
classic RCE primitive. (`rules/03`, `rules/04`)
6. **Banned functions are banned.** No `gets`, `strcpy`/`strcat`/`sprintf`
(use bounded forms or `std::string`/`std::format`), no `system()` with
interpolated input (use `posix_spawn`/`exec*` with an argv array). (`rules/04`)
7. **Build hardened, by default.** `-Wall -Wextra -Werror` plus the OpenSSF
set (`-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -fstack-protector-strong
-fstack-clash-protection -fcf-protection -Wl,-z,relro,-z,now`). Missing
hardening on a network-facing binary is a HIGH finding. (`rules/04`,
`rules/06`)
8. **Shared mutable state is synchronized; data races are CRITICAL.** Guard
with a `mutex`/`scoped_lock` or use `std::atomic` with a justified memory
order. A `-fsanitize=thread` failure is not flaky noise. (`rules/05`)
9. **Sanitizers and a static analyzer gate CI.** A debug/test job runs
ASan+UBSan (and TSan for threaded code); clang-tidy + cppcheck run on every
PR. Untrusted-input parsers get a fuzz target. (`rules/06`)
10. **Prefer the type system to convention.** `enum class` over macros,
`constexpr`/`inline` over `#define`, `gsl::span`/`std::span` over pointer+
length, `[[nodiscard]]` on must-check returns, `explicit` on single-arg
constructors, `override`/`final`. Make misuse fail to compile. (`rules/01`)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!