sp.h:C に高品質で超移植可能な標準ライブラリを与えることで改善されたもの

2026/05/20 22:05

sp.h:C に高品質で超移植可能な標準ライブラリを与えることで改善されたもの

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

The 提供されたサマリーはキーポイントリストとよく一致しており、変更する必要はありません。

サマリー:

このテキストは、過去 1 ヶ年で開発された高品質かつ極めて portable な C 標準ライブラリ「sp.h1」を紹介しています。これはプログラムingu を近代化する一方で libc への依存を最小限に抑えることを目的としています。その核心の革新点は、複雑でしばしば肥大化した libc の構造に依存するのではなく、約 40 つの主要な syscalls に直接相互作用することにあります。単一のヘッダーファイルに収められた 15,000 行を超えるクリーンな C99 コードを包含し、sp.h1 はゼロ初期化によるメモリ管理、可変なグローバル状態の排除、null ターミネーション付き文字列の拒否(代わりに

sp_str_t
を使用し、ポインタと長さを組み合わせる)、およびすべての操作についてエラーを返すことで安全性と予測可能性を実現しています。名前空間構成されたライブラリは
@tags
によって整理されており、最小限のコアのみを提供し、設定を必要としません。本書は、軽量でドロップイン型モジュールとして設計されており、既存の C プロジェクトへの統合が可能で、構造変更が不要です。これにより特定のニーズを満たすものであり、 Entire OS インターフェースを置換したり、既存の libc インターフェースへの準拠を目指したりするものではありません。

portability は厳格な C99 準拠によって達成され、主要なコンパイラ(GCC、Clang、MSVC、MinGW、TCC)を使用して Linux、Windows、macOS、WebAssembly ホストでネイティブにコンパイルすることが可能であり、libc を含めず、あるいは含むことも可能です(Cosmopolitan など)。一方で、珍しいアーキテクチャや小さすぎる使用ケースの一部に対する肥大化したサポートを避けます。パフォーマンス戦略では、特定の使用ケースが必要とする場合にのみ微調整された最適化を行うことを優先し、未知のハードウェア最適化を追いかけて複雑さを犠牲にすることは拒否し、ゼロコピー I/O API を手元に保持します。

実装ではヒープを非基本型(プログラムが所有するメモリ)として扱い、LLVM などの高度な最適化コンパイラを使用してマシンのコード生成を行い、C の強みであるアーキテクチャへの直接コンパイル、最先端のツール群、オペレーティングシステムおよびライブラリで使用される言語との互換性に合わせています。著者は明確に libc の代わりにはならず、近代インターフェースのための柔軟で portable な代替手段であると述べています。協力については Discord (

#sp
チャンネル)、IRC (
#sp
)、または電子メールを通じて歓迎されており、著者はソフトウェアの fundamentals に関するいくつかの誤解を自認しつつも、ライブラリの移植に協力し、フィードバックを受け入れ、実用的な微調整を継続することに意欲的であると強調しています。

本文

sp.h1:高品質で超ポータブルな C 標準ライブラリの開発

概要

過去 1 年間にわたって開発された、C プログラミング言語における新たな基準となる単一ヘッダー形式のライブラリです。

  • 名称:
    sp.h1
  • 規模: ソースコード約 15,000 行(単一ヘッダー形式)
  • ライセンス・公開元: GitHub で公開済み
  • 特徴:
    • libc
      のラッパーではない。
    • 状況に応じて
      libc
      を使用するかしないかを選択可能(デフォルトは不使用)。
    • 野球関連の機能拡張ライブラリも多数付属する。

基本原理

システムコールへの直接アクセス

すべての C ライブラリは、利用可能な最低限の基底機能(システムコール)に対して直接記述されるべきです。

  • OS とコードの間に蓄積された古い実装(くず屑)をシミュレートしたり生成したりする做法は、有用性も生産性もないと判断されます。

libc
は能動的に有害である

libc
に依存することは一時的な解決策のように思えますが、長期的には害となります。

  • 非同期プログラミングの重要性増大: IO 処理において「高速さ」はレジスタ割り当てではなく、適切なカーネル機能の使用にあるためです。
  • 古臭いインターフェース:
    • FILE*
      型のインターフェース(IO の根本単位が不適切)。
    • 部分文字列を「悪質」とみなす設計。
    • これらは単なる不便さを超え、有害です。
  • 方針:
    sp.h1
    はこれらの依存関係を断ち切ることに注力しています。

ヒープは存在しない(メモリ割り当て)

型定義にはアロケータ機能の基底機能が組み込まれています。

typedef enum {
    SP_ALLOCATOR_MODE_ALLOC,
    SP_ALLOCATOR_MODE_FREE,
    SP_ALLOCATOR_MODE_RESIZE,
} sp_mem_alloc_mode_t;

SP_TYPEDEF_FN(
    void*,
    sp_allocator_fn_t,
    void* user_data, sp_mem_alloc_mode_t mode, u64 size, void* ptr
);

typedef struct sp_allocator_t {
    sp_allocator_fn_t on_alloc;
    void* user_data;
} sp_mem_t;
  • 事実の再認識: プログラムが「無から任意量のメモリを割り当てられる」という能力は幻想です。OS はページ単位でメモリを割り当てます。
  • malloc()
    を通じて動作するランタイムは、「ページサイズ未満の割当が可能」という幻覚を提供しているに過ぎません。
  • メモリは「ランタイム」や「ヒープ」のものではなく、プログラムの所有物です。
  • ヒープ割り当てを望むのは自由ですが、これを「非選択型」から**「選択型」**へ転換することが推奨されます。

nullptr
文字列(ヌル終端文字列)は悪魔の業である

ヌル終端文字列 (

\0
) を採用することは以下の機能を制限します:

  • オーナーシップを持たない部分文字列の返還ができない。
  • O(1) の時間複雑度で文字列の長さを知る必要がある場合に不利。
  • レクサーやパーサが人間工学に優れたビューを返せない。
  • インバリッドな中間値を含まずに安全に文字列を構築できない。

代替案:

sp_str_t
(ポインタと長さを持つ文字列)。

  • 既存 API との互換性の問題は一時的でしたが、現在は意味がないと見直されています。
  • パフォーマンスと人間工学を両立したコード例:
sp_str_t content = sp_zero;
sp_io_read_file(mem, path, &content);

sp_ht(sp_str_t, u32) counts = sp_zero;
sp_str_ht_init(mem, counts);
sp_da(sp_str_t) lines = sp_str_split_c8(mem, content, '\n');
sp_da_for(lines, i) {
    sp_da(sp_str_t) words = sp_str_split_c8(mem, lines[i], ' ');

    sp_da_for(words, j) {
        u32* count = sp_str_ht_get(counts, words[j]);
        if (count) {
            *count = *count + 1;
        } else {
            sp_str_ht_insert(counts, words[j], 1);
        }
    }
}

このコードはソースバッファからデータを複製することなく動作し、高級言語のような可読性を保ちつつ最大のパフォーマンスを実現します。

ソフトウェアの一部であり、外側ではない

sp.h1
は完全に開示され、ユーザーが読み、書き換える、再調整できるものです。

  • コア部分: 約 40 のシステムコールのみを使用(唯一のプラットフォーム固有依存)。
  • 配布形式: 設定不要の単一ファイル (
    header
    ) で完結。
  • 構造: 極めて整理されており、
    @tags
    によるタグ付けで検索可能(LLM や人間向け)。
  • ネームスペース: すべての関数が適切に名前空間化されている。

このアプローチにより、OS の複雑な幻想ではなく、真実であるものを薄いながらも有用なものとして統合し、その上から機能構築を行っています。

極めて高い互換性を保つ

sp.h1
C99 で記述されており、あらゆるコンパイラと動作します。

  • プラットフォーム対応: Linux, Windows, macOS, WASM (ブラウザ内)。
  • ツールチェーン: MSVC, MinGW, TCC など。
  • 環境適応:
    libc
    不使用環境、Cosmopolitan OS など、奇妙な環境も対応。
  • サイズと性能: ライブラリが巨大であるからではなく、小さくあるからこそできるすべてを実現しています。

明示的であること

暗黙の動作ではなく、すべての挙動を明示する設計を採用しています:

  • エラーは常に返され、呼び出し側で処理される。
  • 変更可能なグローバル状態が存在しない。
  • メモリ割り当て関数はユーザー定義のアロケータを受け取る。
  • メモリはゼロで初期化される。

非目標(ここまでは対応しない)

既存のインターフェースへの準拠

  • これは
    libc
    ではありません。
  • 必要な場合のみ尊重しますが、
    libc
    使用プログラムへの埋め込みでも無侵入かつ動作保証されます。
  • libc
    のような挙動を期待すべきものではありません。

不明瞭なアーキテクチャや OS への対応

  • 現在の焦点:
    x86_64
    ,
    aarch64
  • WASM: 重要性が増していますが、ネイティブターゲットに次点です。
  • 方針: 非推奨プラットフォームへの対応は行わず、合理的なパッチであればマージを検討しますが、膨らませる予定はありません。

パフォーマンス

  • 立ち位置: 「低レベルの計算依存型パフォーマンスにおいて、搾り取る価値以上の果汁はない」。
  • 設計の難しさ: 未知のハードウェアと使用ケースに対する最適なパフォーマンスを担保するのは困難であり、コードが複雑化します。
  • 推奨: パフォーマンスが極めて重要な場合は、実際の用途とハードウェアに特化したコードを使用すべきです。

除外される最適化:

  • SIMD によるハッシュテーブルのリ書き換え。
  • LIKELY
    やインラインによる微細なコンパイラ手動調整。

検討されている機能:

  • 最適化およびゼロコピー IO のための正しい抽象。
  • データコピーを不要とする API の設計。

バグ修正も優先されますが、過度な最適化には反対です(理由は単に「忙しい」ため)。


お別れの言葉:C はシンプルであるために価値がある

システムプログラミングにおいて C よりも良い言語は存在しないでしょうか?答えはいいえです。なぜなら C こそが以下の条件を唯一満たすから:

  • 任意のマシンコードに直接コンパイルできる
  • 最先端の最適化コンパイラエコシステムが存在する
  • OS および大部分のライブラリと同じ言語で記述されている

C の価値は、単なるレガシーの上に構築されているからではなく、**「シンプルであること」**にあります。

  • LLVM 等の存在により、技術的には誰でも最先端のコンパイラを持ち得ます。
  • 他の言語には型系やツールが存在します。
  • しかし、そのようなサポートが魔法のように機能し、最適化されつつネイティブにアクセスできるプラットフォームは C です。

皆さんと一緒に取り組んでいきたい

このライブラリ開発者として皆様と連携することを楽しみにしています。

  • 支援内容:
    • 非慣用的な環境への移植支援。
    • 疑問点に関する徹底した解説。
    • フィードバックへの丁寧な対応。
  • 私の姿勢:
    • システムプログラミングの天才ではありませんが、多くの誤解から学び、多大な努力と楽しみを経て開発されたソフトウェアです。
    • 「プログラミングが下手」と評されようとも、耳を傾けてまいります。

連絡先:

  • Discord サーバー: お待ちしています。
  • IRC チャンネル:
    #sp
  • メール: ドメインはサイトと同じで、ハンドルネームは私の姓です。

同じ日のほかのニュース

一覧に戻る →

2026/05/24 3:45

私の Writerdeck を語る時が来ました。

## 日本語翻訳: 著者は、6年経った System76 Galago Pro ラップトップを「writerdeck」と名づけたオフライン書写ステーションに変換し、X11、Wayland、およびデスクトップ環境を排する tty ベースの構成で Debian Trixie を実行することでミニマリズムを優先しています。コンテンツが公開共有を目的としているためフルディスク暗号化は省略され、管理には `sudo` ユーザーモデルに切り替えて root ログインが無効化されました。本質的なツールとして、Neovim がテキスト編集に使用され(従来のエディタに代わり)、Debian バックポートからの `kmscon` でスケーラブルなターミナルウィンドウを可能にし、セッション多重化には `tmux` を使用し、インストール済みの Network Manager 経由の `nm-tui` が Wi-Fi/WAN の管理に用いられます。電力モニタリングおよび画面明るさ制御は `acpi` と `light` コマンドで行われ、自動ログインと `.bashrc`内の起動スクリプトにより Neovim が `tmux` セッション内で動作し、ブート時に Vimwiki が起動するようにしています。Syncthing は Vimwiki フォルダをリモートサーバーに同期させ、ブラウザ GUI を必要とせずオフラインファーストなワークスペースを維持するために全てのネットワークアドレスを活用しています。この構成はデジタルの雑多さを削減し、悪い書写習慣を打破助けるとともに、クリエイティブ専門家にとってセキュリティと生産性を向上させます。

2026/05/24 7:25

自分でロールを作るな

## 日本語訳: 要約: 開発者は、暗号化やユーザーインターフェースコンポーネントといった重要な機能に対して独自の実装を即時に停止する必要があります。なぜなら、「自分自身でつくる」というソリューションは過去の実績が証明する通り危険であるためです。最も重要な教訓は、安全性と使い勝手を確保するために、自作コードの代わりに既成でピアレビューされた標準を採用しなければならないことです。独自のカスタム暗号化パッケージには、初期化の不備や予測可能なパターンなどの深刻な欠陥を内包しており、規制産業では財務規制に違反し、高額の罰則を引き起こす可能性があります。セキュリティの問題だけでなく、ネイティブブラウザ要素を置換することは性能低下をもたらし、過剰な JavaScript ロジックによりキーボードスクロールの破損やリンクの読み込み遅延といった問題を引き起こします。さらに、独自のソリューションは自動入力機能など、安全なパスワード管理などの重要なネイティブ機能を排除してしまいます。この傾向は、組み込みブラウザ機能の安定性よりも創造的なツールの構築を優先しており、ユーザー(高齢者のご家族も含まれます)が慣れ親しんだツールを常に再学習することを強いられています。これらの使い勝手に関する落とし穴を防ぎ、規制当局による罰金を避けるためには、開発者はネイティブ要素を置換するのではなく補完する方向へ転換すべきです。これにより、すべてのウェブサイトで一貫した動作を確保できます。

2026/05/21 6:21

私の二画面デスクセットアップ(2025)

## 日本語訳: 著者は、壁を向いた単調なパソコンデスクを部屋の方を向くように回転させることで(ドアを見渡させ、奥行きを追加)、そしてテック専用だった単一の面を、二つの明確なゾーニングに分かれた大規模な USM ハラーデスクに置き換えることにより、ハイブリッドなワークスペースへと成功裡に変化させています。このデザインは、ソーシャルメディアでのフィードバックを受けてから以前の壁を向いた配置が持っていた「古い」外観に対応し、また、未使用のアイテム、おもちゃ、プロジェクトをアナログ側の面に置き続けることで、ストイックなミニマリズムの限界を解決し、アイデアを刺激することを可能にしています。単純にチェアを二つの半分の間で移動させることで強化された明確な精神的境界線により、このセットアップは一つの表面上で「作業」「思考」「子供たちと過ごす時間」という 3 つの異なる機能を発揮します。9 ヶ月の使用後、著者は単一コンピューターの配置に戻る予定はないことを確認しており、むしろミニマリスト的な規律とマキシマリスト的な柔軟性を融合させたこの柔軟なシステムを維持する意欲を持っています。これにより、別々の部屋を必要とせずに、ワークフローと創造的アウトプットを向上させることができます。

sp.h:C に高品質で超移植可能な標準ライブラリを与えることで改善されたもの | そっか~ニュース