mcpField
M
modern-cpp

modern-cpp

github.com/trailofbits開発7.9k1.2k 回インストール今日更新
リポジトリ

modern-cpp について

modern-cppは、C++20、C++23、C++26のイディオムを用いたコードの作成、近代化、レビューを支援するセキュリティ重視のスキルです。安全性を高めるコーディングパターンとコンパイラ強化の指針を示し、機能を実用成熟度別に整理します。

主な機能

  1. 01旧来のパターンを現代的なC++イディオムに置換
  2. 02C++20およびC++23の言語機能を活用
  3. 03コンパイラ強化フラグとサニタイザーの適用
  4. 04安全性を考慮したC++コードのレビュー
  5. 05成熟度に基づくC++26機能の評価

活用シーン

  1. 01セキュリティが重要なC++コードの作成
  2. 02C++20以前のコードの近代化
  3. 03旧来と現代的な実装方法の選択
  4. 04C++イディオムの採用状況のレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/trailofbits/skills --skill modern-cpp

インストール後、Claude Code で/modern-cppを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
anti-patterns.md
compiler-hardening.md
cpp20-features.md
cpp23-features.md
cpp26-features.md
safe-idioms.md

詳細

モダン C++

C++20、C++23、C++26 のイディオムを使ってモダンな C++ を書くためのガイドです。脆弱性の種類をなくし、定型コードを減らすパターンに重点を置き、Trail of Bits のセキュリティ面での知見を取り入れています。

このスキルを使う場面

  • 新しい C++ 関数、クラス、ライブラリを書く
  • 既存の C++ コードをモダン化する(C++20 より前のパターン)
  • レガシーな方法とモダンな方法のどちらを使うか選ぶ
  • セキュリティや安全性が重要な C++ に取り組む
  • モダンなイディオムの採用状況について C++ コードをレビューする

このスキルを使わない場面

  • ユーザーが古い規格を明示的に要求している場合:制約(組み込み環境、レガシー ABI)を尊重してください
  • 純粋な C コード:このスキルは C++ 専用です
  • ビルドシステムに関する質問:CMake、Meson、Bazel の設定は対象外です
  • C++ 以外のプロジェクト:C++ が主要言語ではない混在コードベース

避けるべきアンチパターン

避けるもの代わりに使うもの理由
new/deletestd::make_unique, std::make_sharedメモリーリークや二重解放を防ぎます
所有権を持つ生ポインターstd::unique_ptr, std::shared_ptrRAII による所有権管理
C 配列(int arr[N])std::array<int, N>境界を考慮し、値セマンティクスを提供します
ポインターと長さのパラメーターstd::span<T>非所有で、境界をチェックできます
printf / sprintfstd::format, std::print型安全で、バッファーオーバーフローがありません
C スタイルのキャスト (int)xstatic_cast<int>(x)意図が明確で、監査しやすくなります
#define 定数constexpr 変数スコープがあり、型安全で、デバッグしやすくなります
SFINAE / enable_ifConcepts + requires制約とエラーメッセージが読みやすくなります
エラーコードと出力パラメーターstd::expected<T, E>合成可能で、型安全なエラー処理を実現します
unionstd::variant型安全で、暗黙的な未定義動作がありません
生の mutex.lock()/unlock()std::scoped_lock例外安全で、デッドロックを防ぎます
std::threadstd::jthread自動的に join し、停止トークンをサポートします
assert() マクロcontract_assert (C++26)ツールから認識でき、設定可能です
手動の CRTPDeducing this (C++23)より簡潔で、テンプレートの定型コードが不要です
マクロによるコード生成Reflection (C++26)オーバーヘッドがなく、合成可能です

全項目(30 以上のパターン)については、anti-patterns.md を参照してください。

判断フローチャート

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

機能のティア

機能は規格のバージョンではなく、現在の実用性に基づいてランク付けされています。

ティア 1:今すぐ使う(C++20/23、コンパイラーのサポートが充実)
機能置き換えるもの規格
Concepts + requiresSFINAE、enable_ifC++20
Ranges + views生のイテレーターによるループC++20
std::span<T>ポインターと長さC++20
std::formatsprintf、iostream の連結C++20
三方比較 <=>手動の比較演算子C++20
std::jthreadstd::thread + 手動の joinC++20
指定イニシャライザー位置ベースの構造体初期化C++20
std::expected<T,E>エラーコード、境界での例外C++23
std::print / std::printlnprintf、std::cout <<C++23
Deducing thisCRTP、const/非 const の重複C++23
std::flat_map読み取り中心の用途での std::mapC++23
モナディックな std::optionaloptional に対するネストした if チェックC++23

cpp20-features.md と cpp23-features.md を参照してください。

ティア 2:今すぐ導入する(規格の更新は不要)

C++ の規格バージョンを変更せずに、安全性を向上できます。

  • コンパイラーの強化フラグ — -D_FORTIFY_SOURCE=3, -fstack-protector-strong, -ftrivial-auto-var-init=zero
  • 強化版 libc++ — 約 0.3% のオーバーヘッドで境界チェックを行う -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST
  • CI でのサニタイザー — 最低限 ASan + UBSan、並行処理コードには TSan
  • 警告フラグ — -Wall -Wextra -Wpedantic -Werror

compiler-hardening.md を参照してください。

Tier 3:導入を計画する(C++26、構造の見直しを検討する価値があります)

Reflection は、C++26 の機能の中で最も大きな変革をもたらす機能です。次のものが不要になります。

  • シリアライズの定型コード(構造体ごとの to_json を、汎用関数 1 つに置き換えます)
  • コードジェネレーター(protobuf のコード生成、Qt MOC)
  • マクロベースの登録や、列挙型から文字列への変換のハック

GCC 16(2026 年 4 月)では、Reflection がマージされています。新しいコードは、その恩恵を受けられるよう計画してください。

Tier 4:動向を注視する(C++26、成熟が必要です)
  • Contracts(pre/post/contract_assert) — assert() より優れていますが、仮想関数はサポートされておらず、コンパイラーのサポートも限定的です。新しい API の境界で慎重に導入してください。
  • std::execution(送信側/受信側) — 強力な非同期フレームワークですが、学習曲線が急で、付属するスケジューラーがなく、ドキュメントも不十分です。エコシステムが成熟するまで待ってください。

cpp26-features.md を参照してください。

コンパイラーのハードニング早見表

必須フラグ(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 固有
-Wunsafe-buffer-usage
ハードニングされた libc++(Clang/libc++ のみ)
-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST

Google はこれを Chrome とサーバーフリート全体に導入しました。オーバーヘッドは約 0.3%で、1000 件を超えるバグが見つかり、本番環境のセグメンテーション違反が 30%減少しました。

詳しいガイドは compiler-hardening.md を参照してください。

退けるべき合理化

合理化それが誤りである理由
「警告なしでコンパイルできます」警告は有効にするフラグによって異なります。-Wall -Wextra -Wpedantic を追加してください。
「ASan は本番環境では遅すぎます」サンプリングベースで本番環境の問題を検出できる GWP-ASan を使ってください(オーバーヘッドは約 0%)。
「安全なコンテナーだけを使っています」イテレーターの無効化や、チェックされない optional へのアクセスは、依然として悪用される可能性があります。
「スマートポインターは遅いです」std::unique_ptr のオーバーヘッドは、生ポインターと比べてゼロです。主張する前に測定してください。
「コードにメモリーバグはありません」Google はハードニングされた libc++ を有効にした際に、1000 件を超えるバグを発見しました。他の組織も同様です。
「C++26 の機能はまだ使えません」C++20/23 の機能は使えます。ハードニングフラグはどの標準でも機能します。まずはそこから始めてください。
「モダン C++ は読みづらいです」5 つの出力引数にまたがってエラーコードを確認するより、std::expected のほうが読みやすいです。

ベストプラクティスのチェックリスト

  • 所有権にはスマートポインターを使い、生ポインターは非所有の参照に限って使う
  • 関数の引数には、ポインターと長さの組み合わせより std::span を優先する
  • 型付きエラーで失敗する可能性がある関数には std::expected を使う
  • SFINAE ではなく、コンセプトでテンプレートを制約する
  • すべてのビルドでコンパイラーのハードニングフラグとハードニングされた libc++ を有効にする
  • CI で ASan と UBSan を実行し、並行コードには TSan を追加する
  • 可能な場合は constexpr/consteval を使う(設計上、未定義動作がありません)
  • 戻り値を無視するとバグになりやすい関数には [[nodiscard]] を付ける
  • 値セマンティクスを優先し、union の代わりに std::variant を、enum の代わりに enum class を使う
  • すべての変数を宣言時に初期化する

次に読む

コメント