[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6WJ9B2KPAGQ2AM63V4VEYAC":3,"skill-same:01M6WJ9B2KPAGQ2AM63V4VEYAC":94},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":48,"repositoryHtmlUrl":49,"repositoryHomepageUrl":50,"ownerHtmlUrl":51,"ownerBlogUrl":12,"ownerDescription":52,"updatedAt":53,"install":54,"resources":67},"01M6WJ9B2KPAGQ2AM63V4VEYAC","modern-cpp",null,"Guides C++ code toward modern idioms (C++20\u002F23\u002F26). 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.","nodetool-ai\u002Fnodetool","nodetool-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F164873569?v=4","01M6BXPFDW36K9K1MR8ZH63HG2","nodetool.ai","01M6BXPFJ893XM219GQN60B0WK",635,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"cpp","modern cpp","error","new","when","error codes","expected","printf","concepts","print","with","codes","writing","guides","critical","c++","patterns","Legacy","use","code","security","2026-11-10 10:12:30",false,"---\nname: modern-cpp\ndescription: Guides C++ code toward modern idioms (C++20\u002F23\u002F26). 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.\n---\n\n# Modern C++\n\nGuide 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.\n\n## NodeTool Project Rules\n\nThese rules take precedence over the rest of this skill when you work in\n`native\u002Ftimeline\u002F`. The plan in\n[PLAN-GAPS.md](..\u002F..\u002F..\u002Fnative\u002Ftimeline\u002Fdocs\u002FPLAN-GAPS.md) is the source of\ntruth when the two differ.\n\n- **The standard is C++20.** `CMAKE_CXX_STANDARD` is 20, and the code builds\n  with libc++ (macOS), libstdc++ (Linux) and MSVC (Windows). Do not use\n  C++23 or C++26 features: no `std::expected`, `std::print`, deducing\n  `this`, `std::flat_map`, monadic `std::optional`, contracts or reflection.\n  For a fallible function, follow the surrounding code: `std::optional`, or a\n  result struct with an error string.\n- **Package V owns the compiler flags.** Do not add warning, hardening or\n  sanitizer flags in a package. V adds hardening (`_GLIBCXX_ASSERTIONS`\n  for libstdc++, the libc++ hardening mode, `_FORTIFY_SOURCE=3`,\n  `-fstack-protector-strong`, `-ftrivial-auto-var-init=zero`), the\n  `sanitize` and `tsan` presets, and clang-tidy. Warnings stay `-Wall\n  -Wextra` (MSVC `\u002FW4`). V measures `-Werror` and `-Wpedantic` against a\n  baseline. New code adds no warning.\n- **Qt objects follow Qt ownership.** A `QObject` with a parent is owned.\n  Every `connect()` with a lambda passes a context object. A lambda that can\n  outlive an object holds a `QPointer`. moc and `Q_OBJECT` stay.\n- **C handles have one owner.** Wrap each FFmpeg object, VA surface, Vulkan\n  handle and file descriptor in a `std::unique_ptr` with a deleter or a\n  move-only class.\n- **Output:** the app logs through Qt logging. CLI modes keep the existing\n  `stdout`\u002F`stderr` output. Do not convert existing `fprintf` calls.\n- **Threads:** use `std::jthread` for a new plain thread. Use `QThread` when\n  Qt objects live in the thread. Do not rewrite threads in files that your\n  package does not own.\n- **Modernize only the code you change.** Unrelated modernization in a\n  file you touch is out of scope.\n\n## When to Use This Skill\n\n- Writing new C++ functions, classes, or libraries\n- Modernizing existing C++ code (pre-C++20 patterns)\n- Choosing between legacy and modern approaches\n- Working on security-critical or safety-sensitive C++\n- Reviewing C++ code for modern idiom adoption\n\n## When NOT to Use This Skill\n\n- **User explicitly requires older standard**: Respect constraints (embedded, legacy ABI)\n- **Pure C code**: This skill is C++-specific\n- **Build system questions**: CMake, Meson, Bazel configuration is out of scope\n- **Non-C++ projects**: Mixed codebases where C++ isn't primary\n\n## Anti-Patterns to Avoid\n\n| Avoid | Use Instead | Why |\n|-------|-------------|-----|\n| `new`\u002F`delete` | `std::make_unique`, `std::make_shared` | Eliminates leaks, double-free |\n| Raw owning pointers | `std::unique_ptr`, `std::shared_ptr` | RAII ownership semantics |\n| C arrays (`int arr[N]`) | `std::array\u003Cint, N>` | Bounds-aware, value semantics |\n| Pointer + length params | `std::span\u003CT>` | Non-owning, bounds-checkable |\n| `printf` \u002F `sprintf` | `std::format` (`std::print` is C++23, not in NodeTool) | Type-safe, no buffer overflow |\n| C-style casts `(int)x` | `static_cast\u003Cint>(x)` | Explicit intent, auditable |\n| `#define` constants | `constexpr` variables | Scoped, typed, debuggable |\n| SFINAE \u002F `enable_if` | Concepts + `requires` | Readable constraints and errors |\n| Error codes + out params | `std::expected\u003CT, E>` (C++23; NodeTool uses `std::optional` or a result struct) | Composable, type-safe errors |\n| `union` | `std::variant` | Type-safe, no silent UB |\n| Raw `mutex.lock()\u002Funlock()` | `std::scoped_lock` | Exception-safe, no deadlocks |\n| `std::thread` | `std::jthread` | Auto-join, stop token support |\n| `assert()` macro | `contract_assert` (C++26, not in NodeTool) | Visible to tooling, configurable |\n| Manual CRTP | Deducing `this` (C++23, not in NodeTool) | Simpler, no template boilerplate |\n| Macro code generation | Reflection (C++26, not in NodeTool; moc stays) | Zero-overhead, composable |\n\nSee [anti-patterns.md](.\u002Freferences\u002Fanti-patterns.md) for the full table (30+ patterns).\n\n## Decision Tree\n\n```\nWhat are you doing?\n|\n+-- Writing new C++ code?\n|   +-- Use modern idioms by default (C++20\u002F23)\n|   +-- Choose the newest standard your compiler supports\n|   |   (NodeTool: C++20 only, see NodeTool Project Rules)\n|   +-- See Feature Tiers below\n|\n+-- Modernizing existing code?\n|   +-- Start with Tier 1 (C++20\u002F23) replacements\n|   +-- Prioritize by security impact (memory > types > style)\n|   +-- See anti-patterns.md for the migration table\n|\n+-- Security-critical code?\n|   +-- Enable compiler hardening flags (see below)\n|   +-- Enable hardened libc++ mode\n|   +-- Run sanitizers in CI\n|   +-- See safe-idioms.md and compiler-hardening.md\n|\n+-- Using C++26 features?\n    +-- Reflection: YES, plan for it (GCC 16+)\n    +-- Contracts: cautiously, for new API boundaries\n    +-- std::execution: wait for ecosystem maturity\n    +-- See cpp26-features.md\n```\n\n## Feature Tiers\n\nFeatures are ranked by **practical usability today**, not by standard version.\n\n### Tier 1: Use Today (C++20\u002F23, solid compiler support)\n\n| Feature | Replaces | Standard |\n|---------|----------|----------|\n| Concepts + `requires` | SFINAE, `enable_if` | C++20 |\n| Ranges + views | Raw iterator loops | C++20 |\n| `std::span\u003CT>` | Pointer + length | C++20 |\n| `std::format` | `sprintf`, iostream chains | C++20 |\n| Three-way comparison `\u003C=>` | Manual comparison operators | C++20 |\n| `std::jthread` | `std::thread` + manual join | C++20 |\n| Designated initializers | Positional struct init | C++20 |\n| `std::expected\u003CT,E>` | Error codes, exceptions at boundaries | C++23 |\n| `std::print` \u002F `std::println` | `printf`, `std::cout \u003C\u003C` | C++23 |\n| Deducing `this` | CRTP, const\u002Fnon-const duplication | C++23 |\n| `std::flat_map` | `std::map` for read-heavy use | C++23 |\n| Monadic `std::optional` | Nested if-checks on optionals | C++23 |\n\nSee [cpp20-features.md](.\u002Freferences\u002Fcpp20-features.md) and [cpp23-features.md](.\u002Freferences\u002Fcpp23-features.md).\n\n### Tier 2: Deploy Now (no standard bump needed)\n\nThese improve safety without changing your C++ standard version:\n\n- **Compiler hardening flags** — `-D_FORTIFY_SOURCE=3`, `-fstack-protector-strong`, `-ftrivial-auto-var-init=zero`\n- **Hardened libc++** — `-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST` for ~0.3% overhead bounds-checking\n- **Sanitizers in CI** — ASan + UBSan as minimum; TSan for concurrent code\n- **Warning flags** — `-Wall -Wextra -Wpedantic -Werror` (NodeTool: package V owns the flags and measures `-Werror` against a baseline)\n- **Hardened libstdc++** — `-D_GLIBCXX_ASSERTIONS` bounds-checks `operator[]` and similar calls on GCC's standard library\n\nSee [compiler-hardening.md](.\u002Freferences\u002Fcompiler-hardening.md).\n\n### Tier 3: Plan For (C++26, worth restructuring around)\n\n**Reflection** is the single most transformative C++26 feature. It eliminates:\n- Serialization boilerplate (one generic function replaces per-struct `to_json`)\n- Code generators (protobuf codegen, Qt MOC)\n- Macro-based registration and enum-to-string hacks\n\nGCC 16 (April 2026) has reflection merged. Plan new code to benefit from it.\n\n### Tier 4: Watch (C++26, needs maturation)\n\n- **Contracts** (`pre`\u002F`post`\u002F`contract_assert`) — Better than `assert()`, but no virtual function support and limited compiler support. Adopt cautiously for new API boundaries.\n- **std::execution** (senders\u002Freceivers) — Powerful async framework, but steep learning curve, no scheduler ships with it, and poor documentation. Wait for ecosystem maturity.\n\nSee [cpp26-features.md](.\u002Freferences\u002Fcpp26-features.md).\n\n## Compiler Hardening Quick Reference\n\n### Essential Flags (GCC + Clang)\n\nIn NodeTool, package V sets these flags. A package does not add them.\n\n```\n-Wall -Wextra -Wpedantic -Werror\n-D_FORTIFY_SOURCE=3\n-fstack-protector-strong\n-fstack-clash-protection\n-ftrivial-auto-var-init=zero\n-fPIE -pie\n-Wl,-z,relro,-z,now\n```\n\n### Clang-Specific\n\n```\n-Wunsafe-buffer-usage\n```\n\n### Hardened libc++ (Clang\u002Flibc++ only)\n\n```\n-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST\n```\n\nGoogle deployed this across Chrome and their server fleet: ~0.3% overhead, 1000+ bugs found, 30% reduction in production segfaults.\n\nSee [compiler-hardening.md](.\u002Freferences\u002Fcompiler-hardening.md) for the full guide.\n\n## Rationalizations to Reject\n\n| Rationalization | Why It's Wrong |\n|----------------|----------------|\n| \"It compiles without warnings\" | Warnings depend on which flags you enable. Add `-Wall -Wextra -Wpedantic`. |\n| \"ASan is too slow for production\" | Use GWP-ASan for sampling-based production detection (~0% overhead). |\n| \"We only use safe containers\" | Iterator invalidation and unchecked `optional` access are still exploitable. |\n| \"Smart pointers are slower\" | `std::unique_ptr` has zero overhead vs raw pointers. Measure before claiming. |\n| \"Our code doesn't have memory bugs\" | Google found 1000+ bugs when enabling hardened libc++. So did everyone else. |\n| \"C++26 features aren't available yet\" | C++20\u002F23 features are. Hardening flags work on any standard. Start there. |\n| \"Modern C++ is harder to read\" | `std::expected` is more readable than checking error codes across 5 out-params. |\n\n## Best Practices Checklist\n\n- [ ] Use smart pointers for ownership, raw pointers only for non-owning observation\n- [ ] Prefer `std::span` over pointer + length for function parameters\n- [ ] Use `std::expected` for functions that can fail with typed errors (NodeTool: `std::optional` or a result struct, as the surrounding code does)\n- [ ] Constrain templates with concepts, not SFINAE\n- [ ] Enable compiler hardening flags and hardened libc++ in all builds\n- [ ] Run ASan + UBSan in CI; add TSan for concurrent code\n- [ ] Use `constexpr` \u002F `consteval` where possible (UB-free by design)\n- [ ] Mark functions `[[nodiscard]]` when ignoring the return value is likely a bug\n- [ ] Prefer value semantics; use `std::variant` over `union`, `enum class` over `enum`\n- [ ] Initialize all variables at declaration\n\n## Read Next\n\n- [anti-patterns.md](.\u002Freferences\u002Fanti-patterns.md) — Full legacy-to-modern migration table (30+ patterns)\n- [cpp20-features.md](.\u002Freferences\u002Fcpp20-features.md) — Concepts, ranges, span, format, coroutines\n- [cpp23-features.md](.\u002Freferences\u002Fcpp23-features.md) — expected, print, deducing this, flat_map\n- [cpp26-features.md](.\u002Freferences\u002Fcpp26-features.md) — Reflection, contracts, memory safety improvements\n- [compiler-hardening.md](.\u002Freferences\u002Fcompiler-hardening.md) — Flags, sanitizers, hardened libc++\n- [safe-idioms.md](.\u002Freferences\u002Fsafe-idioms.md) — Security patterns by vulnerability class\n\n## Source\n\nAdapted from [trailofbits\u002Fskills](https:\u002F\u002Fgithub.com\u002Ftrailofbits\u002Fskills\u002Ftree\u002F123037ec8aed26f0d86327cc39137ee5043e5deb\u002Fplugins\u002Fmodern-cpp\u002Fskills\u002Fmodern-cpp)\nunder [CC BY-SA 4.0](..\u002FLICENSE-trailofbits-skills). NodeTool changed this\nfile: it added the NodeTool Project Rules section and the NodeTool notes in\nthe anti-pattern table, the decision tree, Tier 2, the flag reference and\nthe checklist. The reference files are unchanged.\n","# Modern C++\n\nGuide 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.\n\n## NodeTool Project Rules\n\nThese rules take precedence over the rest of this skill when you work in\n`native\u002Ftimeline\u002F`. The plan in\n[PLAN-GAPS.md](..\u002F..\u002F..\u002Fnative\u002Ftimeline\u002Fdocs\u002FPLAN-GAPS.md) is the source of\ntruth when the two differ.\n\n- **The standard is C++20.** `CMAKE_CXX_STANDARD` is 20, and the code builds\n  with libc++ (macOS), libstdc++ (Linux) and MSVC (Windows). Do not use\n  C++23 or C++26 features: no `std::expected`, `std::print`, deducing\n  `this`, `std::flat_map`, monadic `std::optional`, contracts or reflection.\n  For a fallible function, follow the surrounding code: `std::optional`, or a\n  result struct with an error string.\n- **Package V owns the compiler flags.** Do not add warning, hardening or\n  sanitizer flags in a package. V adds hardening (`_GLIBCXX_ASSERTIONS`\n  for libstdc++, the libc++ hardening mode, `_FORTIFY_SOURCE=3`,\n  `-fstack-protector-strong`, `-ftrivial-auto-var-init=zero`), the\n  `sanitize` and `tsan` presets, and clang-tidy. Warnings stay `-Wall\n  -Wextra` (MSVC `\u002FW4`). V measures `-Werror` and `-Wpedantic` against a\n  baseline. New code adds no warning.\n- **Qt objects follow Qt ownership.** A `QObject` with a parent is owned.\n  Every `connect()` with a lambda passes a context object. A lambda that can\n  outlive an object holds a `QPointer`. moc and `Q_OBJECT` stay.\n- **C handles have one owner.** Wrap each FFmpeg object, VA surface, Vulkan\n  handle and file descriptor in a `std::unique_ptr` with a deleter or a\n  move-only class.\n- **Output:** the app logs through Qt logging. CLI modes keep the existing\n  `stdout`\u002F`stderr` output. Do not convert existing `fprintf` calls.\n- **Threads:** use `std::jthread` for a new plain thread. Use `QThread` when\n  Qt objects live in the thread. Do not rewrite threads in files that your\n  package does not own.\n- **Modernize only the code you change.** Unrelated modernization in a\n  file you touch is out of scope.\n\n## When to Use This Skill\n\n- Writing new C++ functions, classes, or libraries\n- Modernizing existing C++ code (pre-C++20 patterns)\n- Choosing between legacy and modern approaches\n- Working on security-critical or safety-sensitive C++\n- Reviewing C++ code for modern idiom adoption\n\n## When NOT to Use This Skill\n\n- **User explicitly requires older standard**: Respect constraints (embedded, legacy ABI)\n- **Pure C code**: This skill is C++-specific\n- **Build system questions**: CMake, Meson, Bazel configuration is out of scope\n- **Non-C++ projects**: Mixed codebases where C++ isn't primary\n\n## Anti-Patterns to Avoid\n\n| Avoid | Use Instead | Why |\n|-------|-------------|-----|\n| `new`\u002F`delete` | `std::make_unique`, `std::make_shared` | Eliminates leaks, double-free |\n| Raw owning pointers | `std::unique_ptr`, `std::shared_ptr` | RAII ownership semantics |\n| C arrays (`int arr[N]`) | `std::array\u003Cint, N>` | Bounds-aware, value semantics |\n| Pointer + length params | `std::span\u003CT>` | Non-owning, bounds-checkable |\n| `printf` \u002F `sprintf` | `std::format` (`std::print` is C++23, not in NodeTool) | Type-safe, no buffer overflow |\n| C-style casts `(int)x` | `static_cast\u003Cint>(x)` | Explicit intent, auditable |\n| `#define` constants | `constexpr` variables | Scoped, typed, debuggable |\n| SFINAE \u002F `enable_if` | Concepts + `requires` | Readable constraints and errors |\n| Error codes + out params | `std::expected\u003CT, E>` (C++23; NodeTool uses `std::optional` or a result struct) | Composable, type-safe errors |\n| `union` | `std::variant` | Type-safe, no silent UB |\n| Raw `mutex.lock()\u002Funlock()` | `std::scoped_lock` | Exception-safe, no deadlocks |\n| `std::thread` | `std::jthread` | Auto-join, stop token support |\n| `assert()` macro | `contract_assert` (C++26, not in NodeTool) | Visible to tooling, configurable |\n| Manual CRTP | Deducing `this` (C++23, not in NodeTool) | Simpler, no template boilerplate |\n| Macro code generation | Reflection (C++26, not in NodeTool; moc stays) | Zero-overhead, composable |\n\nSee [anti-patterns.md](.\u002Freferences\u002Fanti-patterns.md) for the full table (30+ patterns).\n\n## Decision Tree\n\n```\nWhat are you doing?\n|\n+-- Writing new C++ code?\n|   +-- Use modern idioms by default (C++20\u002F23)\n|   +-- Choose the newest standard your compiler supports\n|   |   (NodeTool: C++20 only, see NodeTool Project Rules)\n|   +-- See Feature Tiers below\n|\n+-- Modernizing existing code?\n|   +-- Start with Tier 1 (C++20\u002F23) replacements\n|   +-- Prioritize by security impact (memory > types > style)\n|   +-- See anti-patterns.md for the migration table\n|\n+-- Security-critical code?\n|   +-- Enable compiler hardening flags (see below)\n|   +-- Enable hardened libc++ mode\n|   +-- Run sanitizers in CI\n|   +-- See safe-idioms.md and compiler-hardening.md\n|\n+-- Using C++26 features?\n    +-- Reflection: YES, plan for it (GCC 16+)\n    +-- Contracts: cautiously, for new API boundaries\n    +-- std::execution: wait for ecosystem maturity\n    +-- See cpp26-features.md\n```\n\n## Feature Tiers\n\nFeatures are ranked by **practical usability today**, not by standard version.\n\n### Tier 1: Use Today (C++20\u002F23, solid compiler support)\n\n| Feature | Replaces | Standard |\n|---------|----------|----------|\n| Concepts + `requires` | SFINAE, `enable_if` | C++20 |\n| Ranges + views | Raw iterator loops | C++20 |\n| `std::span\u003CT>` | Pointer + length | C++20 |\n| `std::format` | `sprintf`, iostream chains | C++20 |\n| Three-way comparison `\u003C=>` | Manual comparison operators | C++20 |\n| `std::jthread` | `std::thread` + manual join | C++20 |\n| Designated initializers | Positional struct init | C++20 |\n| `std::expected\u003CT,E>` | Error codes, exceptions at boundaries | C++23 |\n| `std::print` \u002F `std::println` | `printf`, `std::cout \u003C\u003C` | C++23 |\n| Deducing `this` | CRTP, const\u002Fnon-const duplication | C++23 |\n| `std::flat_map` | `std::map` for read-heavy use | C++23 |\n| Monadic `std::optional` | Nested if-checks on optionals | C++23 |\n\nSee [cpp20-features.md](.\u002Freferences\u002Fcpp20-features.md) and [cpp23-features.md](.\u002Freferences\u002Fcpp23-features.md).\n\n### Tier 2: Deploy Now (no standard bump needed)\n\nThese improve safety without changing your C++ standard version:\n\n- **Compiler hardening flags** — `-D_FORTIFY_SOURCE=3`, `-fstack-protector-strong`, `-ftrivial-auto-var-init=zero`\n- **Hardened libc++** — `-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST` for ~0.3% overhead bounds-checking\n- **Sanitizers in CI** — ASan + UBSan as minimum; TSan for concurrent code\n- **Warning flags** — `-Wall -Wextra -Wpedantic -Werror` (NodeTool: package V owns the flags and measures `-Werror` against a baseline)\n- **Hardened libstdc++** — `-D_GLIBCXX_ASSERTIONS` bounds-checks `operator[]` and similar calls on GCC's standard library\n\nSee [compiler-hardening.md](.\u002Freferences\u002Fcompiler-hardening.md).\n\n### Tier 3: Plan For (C++26, worth restructuring around)\n\n**Reflection** is the single most transformative C++26 feature. It eliminates:\n- Serialization boilerplate (one generic function replaces per-struct `to_json`)\n- Code generators (protobuf codegen, Qt MOC)\n- Macro-based registration and enum-to-string hacks\n\nGCC 16 (April 2026) has reflection merged. Plan new code to benefit from it.\n\n### Tier 4: Watch (C++26, needs maturation)\n\n- **Contracts** (`pre`\u002F`post`\u002F`contract_assert`) — Better than `assert()`, but no virtual function support and limited compiler support. Adopt cautiously for new API boundaries.\n- **std::execution** (senders\u002Freceivers) — Powerful async framework, but steep learning curve, no scheduler ships with it, and poor documentation. Wait for ecosystem maturity.\n\nSee [cpp26-features.md](.\u002Freferences\u002Fcpp26-features.md).\n\n## Compiler Hardening Quick Reference\n\n### Essential Flags (GCC + Clang)\n\nIn NodeTool, package V sets these flags. A package does not add them.\n\n```\n-Wall -Wextra -Wpedantic -Werror\n-D_FORTIFY_SOURCE=3\n-fstack-protector-strong\n-fstack-clash-protection\n-ftrivial-auto-var-init=zero\n-fPIE -pie\n-Wl,-z,relro,-z,now\n```\n\n### Clang-Specific\n\n```\n-Wunsafe-buffer-usage\n```\n\n### Hardened libc++ (Clang\u002Flibc++ only)\n\n```\n-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST\n```\n\nGoogle deployed this across Chrome and their server fleet: ~0.3% overhead, 1000+ bugs found, 30% reduction in production segfaults.\n\nSee [compiler-hardening.md](.\u002Freferences\u002Fcompiler-hardening.md) for the full guide.\n\n## Rationalizations to Reject\n\n| Rationalization | Why It's Wrong |\n|----------------|----------------|\n| \"It compiles without warnings\" | Warnings depend on which flags you enable. Add `-Wall -Wextra -Wpedantic`. |\n| \"ASan is too slow for production\" | Use GWP-ASan for sampling-based production detection (~0% overhead). |\n| \"We only use safe containers\" | Iterator invalidation and unchecked `optional` access are still exploitable. |\n| \"Smart pointers are slower\" | `std::unique_ptr` has zero overhead vs raw pointers. Measure before claiming. |\n| \"Our code doesn't have memory bugs\" | Google found 1000+ bugs when enabling hardened libc++. So did everyone else. |\n| \"C++26 features aren't available yet\" | C++20\u002F23 features are. Hardening flags work on any standard. Start there. |\n| \"Modern C++ is harder to read\" | `std::expected` is more readable than checking error codes across 5 out-params. |\n\n## Best Practices Checklist\n\n- [ ] Use smart pointers for ownership, raw pointers only for non-owning observation\n- [ ] Prefer `std::span` over pointer + length for function parameters\n- [ ] Use `std::expected` for functions that can fail with typed errors (NodeTool: `std::optional` or a result struct, as the surrounding code does)\n- [ ] Constrain templates with concepts, not SFINAE\n- [ ] Enable compiler hardening flags and hardened libc++ in all builds\n- [ ] Run ASan + UBSan in CI; add TSan for concurrent code\n- [ ] Use `constexpr` \u002F `consteval` where possible (UB-free by design)\n- [ ] Mark functions `[[nodiscard]]` when ignoring the return value is likely a bug\n- [ ] Prefer value semantics; use `std::variant` over `union`, `enum class` over `enum`\n- [ ] Initialize all variables at declaration\n\n## Read Next\n\n- [anti-patterns.md](.\u002Freferences\u002Fanti-patterns.md) — Full legacy-to-modern migration table (30+ patterns)\n- [cpp20-features.md](.\u002Freferences\u002Fcpp20-features.md) — Concepts, ranges, span, format, coroutines\n- [cpp23-features.md](.\u002Freferences\u002Fcpp23-features.md) — expected, print, deducing this, flat_map\n- [cpp26-features.md](.\u002Freferences\u002Fcpp26-features.md) — Reflection, contracts, memory safety improvements\n- [compiler-hardening.md](.\u002Freferences\u002Fcompiler-hardening.md) — Flags, sanitizers, hardened libc++\n- [safe-idioms.md](.\u002Freferences\u002Fsafe-idioms.md) — Security patterns by vulnerability class\n\n## Source\n\nAdapted from [trailofbits\u002Fskills](https:\u002F\u002Fgithub.com\u002Ftrailofbits\u002Fskills\u002Ftree\u002F123037ec8aed26f0d86327cc39137ee5043e5deb\u002Fplugins\u002Fmodern-cpp\u002Fskills\u002Fmodern-cpp)\nunder [CC BY-SA 4.0](..\u002FLICENSE-trailofbits-skills). NodeTool changed this\nfile: it added the NodeTool Project Rules section and the NodeTool notes in\nthe anti-pattern table, the decision tree, Tier 2, the flag reference and\nthe checklist. The reference files are unchanged.\n",{"name":5,"description":7},"main","2ded107e64519442ef49f8fb0f7f0ba352e17379",".agents\u002Fskills\u002Fmodern-cpp",91,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool","https:\u002F\u002Fnodetool.ai\u002F","https:\u002F\u002Fgithub.com\u002Fnodetool-ai","No-code AI development","2026-11-15 03:27:49",{"source":8,"skillName":5,"commands":55,"prompt":65,"zipAvailable":66},[56,59,62],{"tool":57,"command":58},"npx","npx skills add nodetool-ai\u002Fnodetool --skill modern-cpp",{"tool":60,"command":61},"bunx","bunx skills add nodetool-ai\u002Fnodetool --skill modern-cpp",{"tool":63,"command":64},"pnpm","pnpm dlx skills add nodetool-ai\u002Fnodetool --skill modern-cpp","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002FSKILL.md",true,[68,74,78,82,86,90],{"path":69,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":72,"sourceHtmlUrl":73},"references\u002Fanti-patterns.md","REFERENCE","参考文档",5630,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002Freferences\u002Fanti-patterns.md",{"path":75,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":76,"sourceHtmlUrl":77},"references\u002Fcompiler-hardening.md",7471,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002Freferences\u002Fcompiler-hardening.md",{"path":79,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fcpp20-features.md",7138,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002Freferences\u002Fcpp20-features.md",{"path":83,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":84,"sourceHtmlUrl":85},"references\u002Fcpp23-features.md",7150,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002Freferences\u002Fcpp23-features.md",{"path":87,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":88,"sourceHtmlUrl":89},"references\u002Fcpp26-features.md",7696,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002Freferences\u002Fcpp26-features.md",{"path":91,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":92,"sourceHtmlUrl":93},"references\u002Fsafe-idioms.md",8316,"https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fmodern-cpp\u002Freferences\u002Fsafe-idioms.md",[95,130,160,175,190,215],{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":111,"publishedAt":40},"01M6BY4D93R0Q9400ZHJ04DXP1","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.","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002Fplugins\u002Fchatgpt\u002Fnodetool\u002Fskills\u002Fnodetool\u002FSKILL.md",[101,106],{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":107,"categoryName":108,"taxonomyType":109,"taxonomyTypeDesc":110},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[97,112,113,114,115,116,117,118,119,120,121,122,123,124,37,125,126,127,128,29,129,23],"MCP","mcp server","workflow","workflows","validate","debug","run","graph","server","Media","assets","work","node","visual","generation","collections","media generation","for",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":139,"publishedAt":40},"01M6BY4AEB05ZPBRVD078ATR2H","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\u002Fwan-2.6\u002Ftext-to-video, alibaba\u002Fwan-2.6\u002Fimage-to-video, wan-video\u002Fwan-2.6-t2v, wan-video\u002Fwan-2.6-i2v, wan-video\u002Fwan2.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.","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002Fpackages\u002Fsystem-skills\u002Fwan-2-6-prompting\u002FSKILL.md",[136],{"categoryNo":137,"categoryName":138,"taxonomyType":104,"taxonomyTypeDesc":105},"01JBSEEDCAT000000000000016","图像与多媒体",[140,141,142,143,144,145,146,147,148,149,150,124,151,152,153,154,155,156,157,158,159],"wan 2 6 prompting","prompting","image","generate","Budget","Video","Audio","text","animate","model","flash","only","route","time","line","input","text-to-video","image-to-video","mode","expansion",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":168,"publishedAt":40},"01M6BY47T4748ZG5ZMTAR97ZWZ","video-workflow","Build a reusable NodeTool video workflow for batches or repeated inputs. For a single finished piece, use a storyboard skill.","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002Fpackages\u002Fsystem-skills\u002Fvideo-workflow\u002FSKILL.md",[166,167],{"categoryNo":137,"categoryName":138,"taxonomyType":104,"taxonomyTypeDesc":105},{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},[114,145,169,97,37,170,171,172,173,129,174],"video workflow","reusable","storyboard","build","batches","single",{"skillNo":176,"name":177,"nameZh":6,"description":178,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":179,"categories":180,"keywords":182,"publishedAt":40},"01M6BY4587N2SYN315SXGEMZC3","video-clone","Analyze a reference video and recreate its shot structure with a new product or cast in NodeTool.","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002Fpackages\u002Fsystem-skills\u002Fvideo-clone\u002FSKILL.md",[181],{"categoryNo":137,"categoryName":138,"taxonomyType":104,"taxonomyTypeDesc":105},[145,183,184,185,186,97,187,188,189,29,22],"video clone","clone","product","analyze","reference","cast","structure",{"skillNo":191,"name":192,"nameZh":6,"description":193,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":194,"categories":195,"keywords":197,"publishedAt":40},"01M6BY4257C2KQYYMD9EK6DK8E","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.","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002Fpackages\u002Fsystem-skills\u002Fvideo-audio-continuity\u002FSKILL.md",[196],{"categoryNo":137,"categoryName":138,"taxonomyType":104,"taxonomyTypeDesc":105},[145,146,198,199,200,201,202,203,149,204,205,206,207,208,209,210,211,212,213,214,23],"video audio continuity","continuity","design","boundary","how","why","write","generated","later","back","across","cut","how to","filter","mix","at","veo 3",{"skillNo":216,"name":217,"nameZh":6,"description":218,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":219,"categories":220,"keywords":222,"publishedAt":40},"01M6BY3ZANBSQMZRH4MG55R8Z7","veo-3-prompting","Prompt Google's Veo 3 video line — the five-element shot\u002Fsetting\u002Fsubject\u002Faction\u002Fdialogue 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\u002Fveo3.1 and its fast, lite, image-to-video, first-last-frame and reference-to-video routes, fal-ai\u002Fveo3\u002Fimage-to-video, google\u002Fveo3.1 on atlascloud, google\u002Fveo-3 and google\u002Fveo-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.","https:\u002F\u002Fgithub.com\u002Fnodetool-ai\u002Fnodetool\u002Fblob\u002Fmain\u002Fpackages\u002Fsystem-skills\u002Fveo-3-prompting\u002FSKILL.md",[221],{"categoryNo":137,"categoryName":138,"taxonomyType":104,"taxonomyTypeDesc":105},[223,224,141,214,142,225,226,143,227,228,145,146,148,149,229,230,231,232,233,234,235,189,236,237,238],"veo 3 prompting","veo","google","gemini","fast","first","fal","kie","replicate","fix","auto","references","drift","preview","element","auto-fix"]