SkillAgentSearch skills...

modern-cpp

Guides C++ code toward modern idioms (C++20/23/26)

Install / Use

npx skills add trailofbits/skills --skill modern-cpp

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

81/100

Category

Security

Supported Platforms

Universal

Our assessment of modern-cpp

modern-cpp scores 81/100 on our quality scale, 517th of 658 Security skills we index.

Its SKILL.md is 8.4 KB long, well organised into 17 sections with 4 code examples: a thorough specification that gives an agent plenty to work with.

With 7,225 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
29/30
Structure
20/20
Description
8/15
Adoption
16/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 3 days ago, so modern-cpp is actively maintained.
  • It is released under the CC-BY-SA-4.0 license; check its terms before commercial use.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

modern-cpp compared with similar skills

All 4 of these similar skills score higher than modern-cpp; compare them before choosing.

SkillScoreStarsUpdatedFormat
modern-cpp (this skill)by trailofbits817.2k3d agoSKILL.md
algorithmic-artby anthropics100177.9k4d agoSKILL.md
pptxby anthropics100177.9k4d agoSKILL.md
designby nextlevelbuilder100130.2k5d agoSKILL.md
ui-ux-pro-maxby nextlevelbuilder100130.2k5d agoSKILL.md

Frequently asked questions

How do I install modern-cpp?
Run npx skills add trailofbits/skills --skill modern-cpp. The install tabs above show the steps for each supported agent.
Which AI agents does modern-cpp work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is modern-cpp safe to use?
It is CC-BY-SA-4.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is modern-cpp still maintained?
The repository was last updated 3 days ago, so modern-cpp is actively maintained.

name: modern-cpp description: Guides C++ code toward modern idioms (C++20/23/26). Use when writing new C++ code, modernizing legacy patterns, or working on security-critical C++. Replaces raw pointers with smart pointers, SFINAE with concepts, printf with std::print, error codes with std::expected.

Modern C++

Guide for writing modern C++ using C++20, C++23, and C++26 idioms. Focuses on patterns that eliminate vulnerability classes and reduce boilerplate, with a security emphasis from Trail of Bits.

When to Use This Skill

  • Writing new C++ functions, classes, or libraries
  • Modernizing existing C++ code (pre-C++20 patterns)
  • Choosing between legacy and modern approaches
  • Working on security-critical or safety-sensitive C++
  • Reviewing C++ code for modern idiom adoption

When NOT to Use This Skill

  • User explicitly requires older standard: Respect constraints (embedded, legacy ABI)
  • Pure C code: This skill is C++-specific
  • Build system questions: CMake, Meson, Bazel configuration is out of scope
  • Non-C++ projects: Mixed codebases where C++ isn't primary

Anti-Patterns to Avoid

| Avoid | Use Instead | Why | |-------|-------------|-----| | new/delete | std::make_unique, std::make_shared | Eliminates leaks, double-free | | Raw owning pointers | std::unique_ptr, std::shared_ptr | RAII ownership semantics | | C arrays (int arr[N]) | std::array<int, N> | Bounds-aware, value semantics | | Pointer + length params | std::span<T> | Non-owning, bounds-checkable | | printf / sprintf | std::format, std::print | Type-safe, no buffer overflow | | C-style casts (int)x | static_cast<int>(x) | Explicit intent, auditable | | #define constants | constexpr variables | Scoped, typed, debuggable | | SFINAE / enable_if | Concepts + requires | Readable constraints and errors | | Error codes + out params | std::expected<T, E> | Composable, type-safe errors | | union | std::variant | Type-safe, no silent UB | | Raw mutex.lock()/unlock() | std::scoped_lock | Exception-safe, no deadlocks | | std::thread | std::jthread | Auto-join, stop token support | | assert() macro | contract_assert (C++26) | Visible to tooling, configurable | | Manual CRTP | Deducing this (C++23) | Simpler, no template boilerplate | | Macro code generation | Reflection (C++26) | Zero-overhead, composable |

See anti-patterns.md for the full table (30+ patterns).

Decision Tree

What are you doing?
|
+-- Writing new C++ code?
|   +-- Use modern idioms by default (C++20/23)
|   +-- Choose the newest standard your compiler supports
|   +-- See Feature Tiers below
|
+-- Modernizing existing code?
|   +-- Start with Tier 1 (C++20/23) replacements
|   +-- Prioritize by security impact (memory > types > style)
|   +-- See anti-patterns.md for the migration table
|
+-- Security-critical code?
|   +-- Enable compiler hardening flags (see below)
|   +-- Enable hardened libc++ mode
|   +-- Run sanitizers in CI
|   +-- See safe-idioms.md and compiler-hardening.md
|
+-- Using C++26 features?
    +-- Reflection: YES, plan for it (GCC 16+)
    +-- Contracts: cautiously, for new API boundaries
    +-- std::execution: wait for ecosystem maturity
    +-- See cpp26-features.md

Feature Tiers

Features are ranked by practical usability today, not by standard version.

Tier 1: Use Today (C++20/23, solid compiler support)

| Feature | Replaces | Standard | |---------|----------|----------| | Concepts + requires | SFINAE, enable_if | C++20 | | Ranges + views | Raw iterator loops | C++20 | | std::span<T> | Pointer + length | C++20 | | std::format | sprintf, iostream chains | C++20 | | Three-way comparison <=> | Manual comparison operators | C++20 | | std::jthread | std::thread + manual join | C++20 | | Designated initializers | Positional struct init | C++20 | | std::expected<T,E> | Error codes, exceptions at boundaries | C++23 | | std::print / std::println | printf, std::cout << | C++23 | | Deducing this | CRTP, const/non-const duplication | C++23 | | std::flat_map | std::map for read-heavy use | C++23 | | Monadic std::optional | Nested if-checks on optionals | C++23 |

See cpp20-features.md and cpp23-features.md.

Tier 2: Deploy Now (no standard bump needed)

These improve safety without changing your C++ standard version:

  • Compiler hardening flags — -D_FORTIFY_SOURCE=3, -fstack-protector-strong, -ftrivial-auto-var-init=zero
  • Hardened libc++ — -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST for ~0.3% overhead bounds-checking
  • Sanitizers in CI — ASan + UBSan as minimum; TSan for concurrent code
  • Warning flags — -Wall -Wextra -Wpedantic -Werror

See compiler-hardening.md.

Tier 3: Plan For (C++26, worth restructuring around)

Reflection is the single most transformative C++26 feature. It eliminates:

  • Serialization boilerplate (one generic function replaces per-struct to_json)
  • Code generators (protobuf codegen, Qt MOC)
  • Macro-based registration and enum-to-string hacks

GCC 16 (April 2026) has reflection merged. Plan new code to benefit from it.

Tier 4: Watch (C++26, needs maturation)

  • Contracts (pre/post/contract_assert) — Better than assert(), but no virtual function support and limited compiler support. Adopt cautiously for new API boundaries.
  • std::execution (senders/receivers) — Powerful async framework, but steep learning curve, no scheduler ships with it, and poor documentation. Wait for ecosystem maturity.

See cpp26-features.md.

Compiler Hardening Quick Reference

Essential Flags (GCC + Clang)

-Wall -Wextra -Wpedantic -Werror
-D_FORTIFY_SOURCE=3
-fstack-protector-strong
-fstack-clash-protection
-ftrivial-auto-var-init=zero
-fPIE -pie
-Wl,-z,relro,-z,now

Clang-Specific

-Wunsafe-buffer-usage

Hardened libc++ (Clang/libc++ only)

-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST

Google deployed this across Chrome and their server fleet: ~0.3% overhead, 1000+ bugs found, 30% reduction in production segfaults.

See compiler-hardening.md for the full guide.

Rationalizations to Reject

| Rationalization | Why It's Wrong | |----------------|----------------| | "It compiles without warnings" | Warnings depend on which flags you enable. Add -Wall -Wextra -Wpedantic. | | "ASan is too slow for production" | Use GWP-ASan for sampling-based production detection (~0% overhead). | | "We only use safe containers" | Iterator invalidation and unchecked optional access are still exploitable. | | "Smart pointers are slower" | std::unique_ptr has zero overhead vs raw pointers. Measure before claiming. | | "Our code doesn't have memory bugs" | Google found 1000+ bugs when enabling hardened libc++. So did everyone else. | | "C++26 features aren't available yet" | C++20/23 features are. Hardening flags work on any standard. Start there. | | "Modern C++ is harder to read" | std::expected is more readable than checking error codes across 5 out-params. |

Best Practices Checklist

  • [ ] Use smart pointers for ownership, raw pointers only for non-owning observation
  • [ ] Prefer std::span over pointer + length for function parameters
  • [ ] Use std::expected for functions that can fail with typed errors
  • [ ] Constrain templates with concepts, not SFINAE
  • [ ] Enable compiler hardening flags and hardened libc++ in all builds
  • [ ] Run ASan + UBSan in CI; add TSan for concurrent code
  • [ ] Use constexpr / consteval where possible (UB-free by design)
  • [ ] Mark functions [[nodiscard]] when ignoring the return value is likely a bug
  • [ ] Prefer value semantics; use std::variant over union, enum class over enum
  • [ ] Initialize all variables at declaration

Read Next

Related Skills

View on GitHub
GitHub Stars7.2k
CategorySecurity
Updated3d ago
Forks615

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions