AGENT SKILL

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.

License 许可
AGPL-3.0
最近更新
2026-11-15
Stars
★ 635
Forks
91

01 前言 Front Matter

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.

02 资源文件 6

03 SKILL.md 正文

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.

NodeTool Project Rules

These rules take precedence over the rest of this skill when you work in native/timeline/. The plan in PLAN-GAPS.md is the source of truth when the two differ.

  • The standard is C++20. CMAKE_CXX_STANDARD is 20, and the code builds with libc++ (macOS), libstdc++ (Linux) and MSVC (Windows). Do not use C++23 or C++26 features: no std::expected, std::print, deducing this, std::flat_map, monadic std::optional, contracts or reflection. For a fallible function, follow the surrounding code: std::optional, or a result struct with an error string.
  • Package V owns the compiler flags. Do not add warning, hardening or sanitizer flags in a package. V adds hardening (_GLIBCXX_ASSERTIONS for libstdc++, the libc++ hardening mode, _FORTIFY_SOURCE=3, -fstack-protector-strong, -ftrivial-auto-var-init=zero), the sanitize and tsan presets, and clang-tidy. Warnings stay -Wall -Wextra (MSVC /W4). V measures -Werror and -Wpedantic against a baseline. New code adds no warning.
  • Qt objects follow Qt ownership. A QObject with a parent is owned. Every connect() with a lambda passes a context object. A lambda that can outlive an object holds a QPointer. moc and Q_OBJECT stay.
  • C handles have one owner. Wrap each FFmpeg object, VA surface, Vulkan handle and file descriptor in a std::unique_ptr with a deleter or a move-only class.
  • Output: the app logs through Qt logging. CLI modes keep the existing stdout/stderr output. Do not convert existing fprintf calls.
  • Threads: use std::jthread for a new plain thread. Use QThread when Qt objects live in the thread. Do not rewrite threads in files that your package does not own.
  • Modernize only the code you change. Unrelated modernization in a file you touch is out of scope.

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 is C++23, not in NodeTool) 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> (C++23; NodeTool uses std::optional or a result struct) 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, not in NodeTool) Visible to tooling, configurable
Manual CRTP Deducing this (C++23, not in NodeTool) Simpler, no template boilerplate
Macro code generation Reflection (C++26, not in NodeTool; moc stays) 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
|   |   (NodeTool: C++20 only, see NodeTool Project Rules)
|   +-- 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 (NodeTool: package V owns the flags and measures -Werror against a baseline)
  • Hardened libstdc++ — -D_GLIBCXX_ASSERTIONS bounds-checks operator[] and similar calls on GCC's standard library

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)

In NodeTool, package V sets these flags. A package does not add them.

-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 (NodeTool: std::optional or a result struct, as the surrounding code does)
  • [ ] 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

Source

Adapted from trailofbits/skills under CC BY-SA 4.0. NodeTool changed this file: it added the NodeTool Project Rules section and the NodeTool notes in the anti-pattern table, the decision tree, Tier 2, the flag reference and the checklist. The reference files are unchanged.

04 同仓库更多 Skills

nodetool-ai
nodetool-ai/nodetool

nodetool

Use the NodeTool MCP server to build, validate, run, and debug visual AI workflows, and to work with assets, collections, and jobs. Use when the user mentions NodeTool or asks for a workflow graph, a node, or a media generation run on their NodeTool server.

开发工程师Skill与智能体开发
★ 635
nodetool-ai
nodetool-ai/nodetool

wan-2-6-prompting

Prompt Alibaba's Wan 2.6 video — text-to-video with a global style line plus timing-bracketed shots, and image-to-video that describes only what changes over time. Covers the shot-mode switch per provider, the prompt budget, negative prompts, motion intensity wording, audio input and prompt expansion. Use whenever the model id names a Wan 2.6 video route (alibaba/wan-2.6/text-to-video, alibaba/wan-2.6/image-to-video, wan-video/wan-2.6-t2v, wan-video/wan-2.6-i2v, wan-video/wan2.6-i2v-flash) on generate_video, animate_image or a TextToVideo node. Not for Wan 2.5 or 2.7, or the Wan 2.6 image routes.

图像与多媒体
★ 635
nodetool-ai
nodetool-ai/nodetool

video-workflow

Build a reusable NodeTool video workflow for batches or repeated inputs. For a single finished piece, use a storyboard skill.

图像与多媒体Skill与智能体开发
★ 635
nodetool-ai
nodetool-ai/nodetool

video-clone

Analyze a reference video and recreate its shot structure with a new product or cast in NodeTool.

图像与多媒体
★ 635
nodetool-ai
nodetool-ai/nodetool

video-audio-continuity

Keep sound continuous across a multi-scene piece cut from generated video — why one clip per scene hard-cuts the audio at every boundary, when to write all the scenes into a single generation instead, the sound-design vocabulary that survives a provider's copyright filter, and how to check the length, the aspect ratio and the mix of what came back. Use when a piece has more than one scene and the video model writes its own audio (Seedance 2, Veo 3, MiniMax H3, Kling 2.6 and later), or when a cut's sound drops out at the shot changes.

图像与多媒体
★ 635
nodetool-ai
nodetool-ai/nodetool

veo-3-prompting

Prompt Google's Veo 3 video line — the five-element shot/setting/subject/action/dialogue structure, the cinematography vocabulary it reads directly, duration and aspect-ratio tradeoffs, the audio and auto-fix switches per provider, and the fixes for visual drift, temporal inconsistency and audio mismatch. Use whenever the model id contains veo3 or veo-3 (fal-ai/veo3.1 and its fast, lite, image-to-video, first-last-frame and reference-to-video routes, fal-ai/veo3/image-to-video, google/veo3.1 on atlascloud, google/veo-3 and google/veo-3.1 on replicate, kie's veo-3-1, and Gemini's own veo-3.1-generate-preview) on generate_video, animate_image, generate_video_from_references or a TextToVideo node.

图像与多媒体
★ 635