背景
ライブラリを細かいヘッダに分割していると、各ヘッダが自分の使う std ヘッダを個別に #include するため、バンドル出力に kept ライブラリの同一 include 行が多数散らばる。実例として、atcoder-env の分割ライブラリ構成では提出コードの include 行 117 行のうちユニークなのは 61 行だった (<type_traits> ×9、<string> ×8 など)。
2 回目以降の include は include guard により no-op なので実害はなく、どの行を「重複」とみなすかはユーザーのライブラリ構成に依存するため、除去は risundle の責務ではないと考える。
提案
docs/cheatsheet.md (と .ja) に、後処理で重複 include を潰すレシピを追記する:
risundle main.cpp | awk '{ print (/^#include/ && seen[$0]++) ? "" : $0 }' > submission.cpp
- 同一の
#include 行の初出だけを残し、2 回目以降を空行に置換する
- 行削除ではなく空行置換なのは、出力中の
#line ディレクティブと物理行番号の対応を崩さないため (削除すると以降の診断メッセージの行番号がずれる)
- include guard 済みヘッダの再 include は no-op なので意味論的に安全
- 制限: 表記が異なるが推移的に包含済みの include (例:
<atcoder/all> 包含下の <atcoder/modint>) はテキスト比較では残る
上記ワンライナーは実際のバンドル出力 (438 行) で include 117 行 → 61 行・総行数不変となり、コンパイル・実行とも問題ないことを確認済み。
🤖 この issue は Claude Code により生成されました
背景
ライブラリを細かいヘッダに分割していると、各ヘッダが自分の使う std ヘッダを個別に
#includeするため、バンドル出力に kept ライブラリの同一 include 行が多数散らばる。実例として、atcoder-env の分割ライブラリ構成では提出コードの include 行 117 行のうちユニークなのは 61 行だった (<type_traits>×9、<string>×8 など)。2 回目以降の include は include guard により no-op なので実害はなく、どの行を「重複」とみなすかはユーザーのライブラリ構成に依存するため、除去は risundle の責務ではないと考える。
提案
docs/cheatsheet.md (と .ja) に、後処理で重複 include を潰すレシピを追記する:
#include行の初出だけを残し、2 回目以降を空行に置換する#lineディレクティブと物理行番号の対応を崩さないため (削除すると以降の診断メッセージの行番号がずれる)<atcoder/all>包含下の<atcoder/modint>) はテキスト比較では残る上記ワンライナーは実際のバンドル出力 (438 行) で include 117 行 → 61 行・総行数不変となり、コンパイル・実行とも問題ないことを確認済み。
🤖 この issue は Claude Code により生成されました