1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cのコードレビューが属人化していたので、機械化できる層を4段に分けて潰した話(L0コンパイラ〜L3監査)

1
Last updated at Posted at 2026-07-13

自分は現役のフリーランスCエンジニアで、組み込み寄りの案件が多い。ずっと困っていたのがコードレビューの属人化だった。レビュアーによって指摘のバラつきが大きいし、MISRA準拠の確認は目視で毎回時間が溶ける。「前に指摘したやつ、本当に直った?」を定量的に追えない。

そこで、「人が目で見る前に機械で潰せる層」を段階に分けて整理した。結論だけ先に言うと、レビューで人間が頭を使うべきは設計判断だけにして、それ以外は L0〜L3 の4段で機械に落とす、という運用にしたら属人性がかなり消えた。この記事はその4段の中身と、各段で何が拾えて何が拾えないかの記録。

前提: 最初の砦はコンパイラ(L0)。自作ツールではない

先に大事なことを書いておく。C の安全性チェックの一段目は、静的解析ツールでも自作ツールでもなく、コンパイラの警告だ。ここをサボって高級なツールから入るのは順番が逆で、コスパが悪い。

自分は CI とローカルの両方で、まずこれを全部有効にして警告ゼロを強制している。

# GCC
gcc -std=c11 -Wall -Wextra -Wpedantic -Werror -fanalyzer -c foo.c

# Clang
clang -std=c11 -Weverything -Werror -c foo.c

-Werror で警告をビルドエラーに昇格させ、「L0 の警告がゼロにならない PR はレビューに入らない」を運用ルールにした。GCC の -fanalyzer は NULL 参照や解放後使用まで踏み込んでくれるし、Clang の -Weverything は一旦全部出してからノイズを個別に抑制していく。

契約をコンパイラに教えるのも L0 の仕事だ。

// NULL を渡してはいけない引数はコンパイラに宣言する(NULL 契約の第一選択)
void parse(const char *buf) __attribute__((nonnull));

// 戻り値を無視されたら困る関数は警告させる
int try_lock(lock_t *l) __attribute__((warn_unused_result));

nonnullwarn_unused_result を付けておくと、契約違反をコンパイル時に弾ける。ここまでで、低級なミスの大半は人間のレビュー前に死ぬ。

L1: コンパイラが見ないパターンを clang-tidy / cppcheck で拾う

L0 を通っても残るものがある。命名規約、関数の複雑度、一部の未初期化・範囲外、コンパイラが警告にしないイディオムの誤用。ここは clang-tidy と cppcheck の担当。

clang-tidy foo.c -- -std=c11
cppcheck --enable=all --std=c11 foo.c

L0+L1 で、「機械が定型で判定できる欠陥」はだいたい網羅できる。ここまでは無料の既存ツールで完結する。まずここを固めるのが先。

L0〜L1 で埋まらない層が、属人性の正体だった

問題は、L0/L1 を全部やっても残る層があることだった。自分の現場でレビューが属人化していた本当の原因はここにある。

  • MISRA 準拠の体系的なチェック(ルール単位で「どこが違反か」を一覧にしたい)
  • 仕様書との照合(「この関数、仕様どおりに例外処理してる?」をコードと突き合わせたい)
  • リスクの分類(検出を重大度で仕分けして、直す順番を決めたい)
  • 大規模コードベースでの影響範囲(数万行で「この変更、どこに波及する?」)
  • 修正の定量追跡(前回の指摘が今回で減ったか)

これらは clang-tidy/cppcheck のスコープの外で、結局レビュアーの経験に頼っていた。=属人化。

L2: 設計レビューの壁打ちは creview(無料)に投げる

「設計として妥当か」の一次判断は、C 設計レビュー AI の creview に投げるようにした。無料で配布している。GitHub にある(github.com/ponfreelance/creview)。ここは人間のレビューの前段の壁打ち役。

L3: 監査レベルは自分で作った——CSAF

そして L0〜L2 で埋まらなかった「MISRA 準拠チェック・仕様書照合・リスク分類・監査レポート」を、自分用に作ったのが CSAF(C-Safety-audit-framework) だ。現場の課題から生まれたので、必要なものだけ入っている。

  • libclang による AST 解析。ソースをテキストとして正規表現で舐めるのではなく、Clang の構文木を直接読む。コメント中の偶然の一致や記述スタイルの違いに惑わされない
  • MISRA 違反検出だけでなく、仕様書との照合も AST ベース
  • 検出をリスク分類し、HTML レポートに出力
  • ローカル完結(コードを外に出さない。受託だと重要)
csaf audit --mode SAFETY --repo ./src

コマンド一発で、レビュー前に「機械で言えることは全部言い終わった」状態を作れる。人間のレビューは、そこから先の設計判断だけに集中できる。

商用の静的解析ツール(数十万円〜)の基本機能に相当する部分を、買い切り ¥4,980・ソースコード付きにしてある。自分のプロジェクト独自ルールも追加できる。全部を自作するのは大変だけど L3 の層は欲しい、という人向け。

CSAF(¥4,980・BOOTH): https://cutt.ly/5tKoVA2h

ブラウザで30秒体験できるデモを置きました(2026-07 追記)

CSAF がどんな指摘を出すか、インストール不要で試せる簡易デモを用意しました。
C コードを貼ると、危険箇所を A / B / C のリスク分類つきで指摘します
(AI による体験版です。製品版は libclang による決定的な静的解析で、結果の揺らぎはありません)。

👉 CSAF 体験デモ(ブラウザで動きます)
※実行には Claude アカウント(無料プラン可)でのログインが必要です

まとめ: 4段に分けると「人が頭を使う場所」だけ残る

何を ツール 費用
L0 コンパイラ警告ゼロを強制 gcc/clang の -Wall -Wextra -Werror -fanalyzer 無料
L1 定型パターン検出 clang-tidy / cppcheck 無料
L2 設計レビューの壁打ち creview 無料
L3 MISRA準拠・仕様照合・リスク分類・監査レポート CSAF ¥4,980

順番が大事で、L0 を飛ばして上の層から入らない。まずコンパイラで警告ゼロ、次に clang-tidy/cppcheck、それでも埋まらない監査層だけを L2/L3 で埋める。この順で機械に落とすと、レビューで人間が見るのは「設計として正しいか」だけになって、属人性がかなり消えた。

著者:ぽん(@pon_freelance

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?