cpp-systems について
C++のシステムやライブラリの実装・レビュー向けスキルです。C++17を基準とし、該当する場合はC++20機能にも触れます。リソース所有権、互換性、リポジトリ規約を重視し、ビルドや解析、テストで検証します。
主な機能
- 01RAIIと所有権の指針
- 02C++17基準とC++20の補足
- 03API・ABI互換性の実践
- 04リポジトリ規約とツール
- 05ビルド・解析・サニタイザー検査
活用シーン
- 01C++ライブラリの変更実装
- 02リソース寿命と所有権のレビュー
- 03公開APIとABIの維持
- 04ビルドとマルチスレッドコードの検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ iliaal/ ai-skills --skill cpp-systemsインストール後、Claude Code で/cpp-systemsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
SPEC.mdreferences/api-and-abi.mdcmake-and-tooling.mdconcurrency-and-verification.mdlegibility-standard.mdvalue-and-interface-design.md詳細
C++ システム&ライブラリ
C++17 を基準とし、プロジェクトの規格で許可されている場合は C++20 の機能も取り上げます。手動でのライフタイム管理、ステータス列挙型、ネイティブ拡張など、純粋な C については ia-c-systems スキルを参照してください。
作業ルール
- リソースの所有権を明確にし、すべての終了経路で解放されるよう RAII を使用します。
- 借用ビューは元となるストレージのライフタイム内に保ち、特殊メンバーを変更する際はコピー/ムーブの動作を確認します。
- プロジェクトのエラーモデルとサポートされる言語規格に従います。
- ABI を維持し、ロックを保持している間、または無効化される可能性のあるコンテナーイテレーターを使っている間は、未知のコールバックを呼び出さないでください。
リポジトリの規約はこのスキルより優先されます
CMakeLists.txt で CXX_STANDARD を確認し、.clang-format と .clang-tidy を読み、編集を始める前に隣接する翻訳単位を 2 つ読んでください。以下のルールと矛盾する場合は、リポジトリの規約を優先します。
実際に起きる矛盾は次のとおりです。
| ローカルの制約 | その結果 |
|---|---|
-fno-exceptions | エラー処理にはコードまたは expected に類するものを使います。コンストラクターでは回復可能なエラーを報告できないため、失敗する可能性のあるファクトリーを使うか、有効なフォールバック状態を構築します。new (std::nothrow) は、プロジェクトの OOM ポリシーが null を検出して回復する場合に限って使います。ポリシーが終了であれば、通常の new で問題ありません |
| C++17 未満に固定された規格 | std::optional/string_view/構造化束縛/if constexpr は使えません。使用する前に確認してください |
| ABI 安定性が必要な公開ヘッダー | レイアウト変更、インライン関数の変更、仮想関数の追加は禁止です。ABI リファレンスを読み込んでください |
| 組み込みまたはフリースタンディングのターゲット | RTTI が使えない、ホットパスで動的割り当てができない、STL コンテナーが使えない可能性があります |
所有権と RAII
すべてのリソースには所有者が 1 つだけあり、その所有者はデストラクターでリソースを解放するオブジェクトです。アプリケーションコードで new または delete を直接使うのは不具合です。
- 単独所有には
std::unique_ptr<T>を使います。これがデフォルトであり、通常のポインターと比べてもコストはかかりません。 std::shared_ptr<T>は、ライフタイムを本当に共有していて、「所有者が利用者より長く生存する」という形では表現できない場合に限って使います。最初ではなく、3 番目に検討してください。- 所有権の循環を断つには
std::weak_ptr<T>を使います。LeakSanitizer は、どのルートからも到達できない循環は報告しますが、グローバルなど登録済みのルートから到達できる循環は報告しません。また、検出結果はプラットフォームや設定によって異なります。これらの検出をサニタイザーに頼らないでください。 - 生の
T*とT&は非所有の参照を意味し、その用途では適切です。unique_ptrを値で受け取るパラメーターは所有権を引き取ることを示し、T*を受け取るパラメーターは所有権を引き取らないことを示します。 - 新しい公開 API で借用する連続範囲を扱う場合は、
std::span<T>(C++20)またはポインターと長さの組み合わせを使います。const std::vector<T>&では、それ以外のコンテナーをすべて拒否するためです。C++17 が基準の場合、または呼び出し元がすべてベクターを使う内部コードの場合は、const std::vector<T>&で問題なく、よりシンプルです。
ゼロの規則:何も所有しないクラスでは、デストラクター、コピー、ムーブを宣言しません。自らリソースを管理するメンバーを組み合わせれば、5 つすべての特殊メンバーが自動的に正しく実装されます。5 の規則:デストラクター、コピーコンストラクター、コピー代入、ムーブコンストラクター、ムーブ代入のいずれかを宣言した場合、作成者は 5 つすべてについて検討する必要があります。ユーザー宣言のデストラクターがあると暗黙のムーブ操作は抑制されるため、デストラクターを追加したクラスが、それまでムーブしていた箇所でいつの間にかディープコピーを行うようになることがあります。
規律
- 破壊的変更が求められていない限り、動作と API 互換性を維持します。公開ヘッダーの変更は、単なる整理ではなく、意思決定です。
- 1 つの呼び出し箇所のために、テンプレート、継承階層、ポリシーパラメーターを導入しないでください。
- ファイルが使うものは
#includeしてください。他のヘッダーからの推移的なインクルードに依存しないでください。 - ヘッダーの名前空間スコープで
using namespaceを使わないでください。完全修飾するか、関数本体内にusingの範囲を限定してください。 - 制約によって逸脱が必要な場合は、逸脱した箇所にコメントを記し、その制約を明記してください。
検証
-Wall -Wextra -Wpedantic -Wshadow -Wconversion -Werrorを指定してビルドがエラーなく完了することclang-tidyが差分に新たな指摘を報告しないこと-fsanitize=address,undefinedを指定してテストが実行され、報告がゼロであること- 変更がスレッド化されたコードに及ぶ場合は、TSan で実行して報告がゼロであること。上記の警告オプション一式ではロックの誤用は検出できません
clang-format --dry-run --Werrorで差分が生じないこと- 生の
new/deleteを新たに使わないこと。unique_ptrで十分な箇所でshared_ptrを新たに使わないこと - デストラクターを追加したクラスについて、ムーブ操作を確認すること
タスク固有のリファレンス
該当する動作を実装またはレビューする前に、関連するリファレンスを読んでください。
- const 性、エラー、API/ABI の変更、テンプレート、または標準ライブラリの動作については、value-and-interface-design.md を参照してください。
- スレッド処理、コンパイラーの設定、テスト、またはビルド分析については、concurrency-and-verification.md を参照してください。
該当するトピックに応じて、既存の専門リファレンスも参照してください。