Modern Cpp logo

Modern Cpp

OrganizationPopular
trailofbits
modern-cpp

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.

Overview

Publishertrailofbits
Repositoryskills
Skill namemodern-cpp
Stars
7.1K
Forks
611
Bundled files
6
LicenseCC-BY-SA-4.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 6 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by trailofbits on GitHub. Read the source before you install it.

Installation

Install the Modern Cpp AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/trailofbits/skills.git /tmp/skills
mkdir -p .claude/skills
cp -r /tmp/skills/plugins/modern-cpp/skills/modern-cpp .claude/skills/modern-cpp
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Modern Cpp in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Modern Cpp on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Modern Cpp is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

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

AvoidUse InsteadWhy
new/deletestd::make_unique, std::make_sharedEliminates leaks, double-free
Raw owning pointersstd::unique_ptr, std::shared_ptrRAII ownership semantics
C arrays (int arr[N])std::array<int, N>Bounds-aware, value semantics
Pointer + length paramsstd::span<T>Non-owning, bounds-checkable
printf / sprintfstd::format, std::printType-safe, no buffer overflow
C-style casts (int)xstatic_cast<int>(x)Explicit intent, auditable
#define constantsconstexpr variablesScoped, typed, debuggable
SFINAE / enable_ifConcepts + requiresReadable constraints and errors
Error codes + out paramsstd::expected<T, E>Composable, type-safe errors
unionstd::variantType-safe, no silent UB
Raw mutex.lock()/unlock()std::scoped_lockException-safe, no deadlocks
std::threadstd::jthreadAuto-join, stop token support
assert() macrocontract_assert (C++26)Visible to tooling, configurable
Manual CRTPDeducing this (C++23)Simpler, no template boilerplate
Macro code generationReflection (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)

FeatureReplacesStandard
Concepts + requiresSFINAE, enable_ifC++20
Ranges + viewsRaw iterator loopsC++20
std::span<T>Pointer + lengthC++20
std::formatsprintf, iostream chainsC++20
Three-way comparison <=>Manual comparison operatorsC++20
std::jthreadstd::thread + manual joinC++20
Designated initializersPositional struct initC++20
std::expected<T,E>Error codes, exceptions at boundariesC++23
std::print / std::printlnprintf, std::cout <<C++23
Deducing thisCRTP, const/non-const duplicationC++23
std::flat_mapstd::map for read-heavy useC++23
Monadic std::optionalNested if-checks on optionalsC++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

RationalizationWhy 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

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Modern Cpp AI skill do?

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.

Why use Modern Cpp on TypingMind?

Because you install it once and use it with any model. Modern Cpp is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Modern Cpp in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/trailofbits/skills/tree/main/plugins/modern-cpp/skills/modern-cpp. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Modern Cpp?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Modern Cpp?

As many as you like. As long as a model supports skills, you can use Modern Cpp with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Modern Cpp AI skill free?

Yes. It is published on GitHub by trailofbits under the CC-BY-SA-4.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇