/note/tech

C言語を置き換える言語はどうあるべきか

要約:

■ 1. 問題意識

  • C言語の安全性の問題:
    • C言語は今でも重要な言語だが、安全性に欠ける
    • 「C言語より安全」と謳う言語は多いが、その実装の多くに何らかの形でC言語が使われている
    • Goは例外かもしれない
  • 基礎部分の脆弱性:
    • Python、PHP、Rubyの「中」が安全でも、基礎にC言語の部分があればそこを破られる可能性がある
  • 本稿の問い:
    • C言語を置き換えるプログラミング言語は作れるのか
    • 作れたとして成功できるのか

■ 2. C言語が使われている領域

  • OSの実装:
    • LinuxはRustが使えるようになったが、コードの大半はC言語で書かれている
    • 他のOSもC、C++、アセンブリー言語で書かれたものが多いと考える
    • 置き換える言語はOSの実装に使える必要がある
  • libc/libmの実装:
    • スクリプト言語で使える数学関数はC言語やC++で実装されていることが多い
    • 各言語のランタイムはlibcのmallocに依存しているケースが多い
    • 一斉に全部変えるのでない限り、libcはインターフェースとして残る
    • 置き換える言語はlibc、libm、mallocの実装に使える必要がある
    • できれば浮動小数点数の細かい制御もできてほしい
  • 言語処理系の実装:
    • Python、Ruby、PHPの主要な処理系はC言語で書かれている
    • JavaScriptの主要な処理系はC++で書かれている
    • コンパイラー型の処理系でも、GCなどのランタイムはC言語で書かれていることが多い
    • 置き換える言語はGCやJITコンパイラーを含め、言語処理系の実装に使える必要がある
  • 性能重視のソフトウェア:
    • 性能上の理由でC言語やC++で書かれるソフトウェアは多い
    • 置き換える言語は性能を出せる必要がある

■ 3. 置き換える言語に求める性質

  • 既出の要件:
    • OSの記述に使える
    • mallocやGCの実装ができる
    • 性能を出せる
  • 移植性:
    • C言語はAVRのような8ビットマイコンからスーパーコンピューターまでを射程にできる
    • WebAssemblyにコンパイルすればブラウザーでも動く
    • このような言語は他になかなかない
    • 置き換える言語にも8ビットマイコンで動いてほしいが、欲張りすぎかもしれない
  • 独立した処理系の作りやすさ:
    • C言語には複数の処理系があり、対応コンパイラーがなければ自作もできる
    • 博士号持ちが1ダース必要な難易度ではなく、その辺のおっさんが片手間で作れる程度であってほしい
    • AIがある今は、難易度はそこまで問題ではないかもしれない
  • 実装を容易にする型システム:
    • 型システムが複雑すぎないことが必要
    • 型システムの一部を無視してもコード生成ができる必要がある
    • PythonやTypeScriptの型注釈を無視しても実行できる性質を想定している
  • 習得難易度:
    • 平均的なプログラマーが習得するための難易度も適度に低い必要がある
  • 浮動小数点数の扱い:
    • C言語は浮動小数点数の扱いが相対的に上手い
    • 丸めモードの制御があり、C23では静的な制御も入った
    • 浮動小数点例外へのアクセス、FMAの短縮の制御がある
    • 十六進浮動小数点数リテラル、C23で追加された十進浮動小数点数がある
    • 未対応のコンパイラーもあるが、仕様にあるので既存コンパイラーの改善や新規作成で対応できる
    • 置き換える言語も浮動小数点数の扱いが上手であってほしい
  • ABIの安定性:
    • C言語はABIが安定しており、言語よりABIの方が大事だという人もいる
    • 規格書でABIを定めてはいないが、安定したABIを持たせる注意は払われている
    • intmax_tの問題もこの点につながる
    • 置き換える言語もC言語のABIを喋れてほしい
  • エイリアスの制御:
    • SIMDのための自動ベクトル化には、C言語のrestrictが有益
    • しかしrestrictは仕様が難解なうえ、機械的な検査がされない
    • 置き換える言語はエイリアスを制御できてほしい
    • 分離論理を勉強すればよいと思いつつ、まだやっていない

■ 4. 安全性の保証

  • C言語の危険性:
    • ポインターの扱いを誤ると即死し、最悪の場合は攻撃者に任意コード実行を許す
  • メモリー安全性:
    • Rust方式がよいのか他の方法があるのかは詳しくないが、メモリー安全性は必須
    • サイバー攻撃が激化する現代、言語レベルでメモリー安全性を保証しないものはC言語の置き換えを名乗れない
  • 範囲チェックの除去:
    • 効率のために配列の範囲チェックを外す手段が必要なケースはある
    • その場合は添字が範囲内であることを定理証明の形で保証することになる
  • 形式検証との連携:
    • AIで証明が作りやすくなった今、定理証明支援系やモデル検査器との連携をやりやすくしてほしい
    • C言語にはコメントでアノテーションするFrama-Cがあるが、もっと言語に統合されていてほしい
    • MoonBitのFormal Verification連携機能のようなものをイメージしている
  • 形式検証と処理系の作りやすさの両立:
    • コンパイラー作者に定理証明支援系等の実装まで求めると、独立した処理系の作りやすさを損なう
    • 形式検証は取り外し可能とし、検証なしでも実行コードを生成できる必要がある
    • コンパイラーの選択肢は、検証を外部に投げる、性質を仮定する、性質を信用しないのいずれか
  • 部分的な検証:
    • 全部やるか全くやらないかの2択ではなく、一部未証明でもとりあえず動かせることが望ましい

■ 5. C言語との相互運用

  • 移行期間の共存:
    • C言語を一斉に新言語へ置き換えるのは非現実的で、移行期間は共存できてほしい
    • AIがもっと進歩すれば一斉置き換えも可能かもしれない
    • C言語のヘッダーを取り込む機能が必要
    • 新言語の関数等をC言語から使うためのヘッダー生成機能が必要
  • 相互運用機能の位置付け:
    • 最終的にC言語を置き換えるなら、ソースレベルの相互運用はいずれ無用の長物になる
    • 相互運用は言語やコンパイラーのコアではなく、bindgenのようなツールで対応するのが筋がよい

■ 6. 結び

  • 現実的な道と夢:
    • C言語は普及しすぎており、全て置き換えるのは夢物語かもしれない
    • 安全性のためのアノテーション付与や、徐々にRustへ置き換えるのが現実的かもしれない
    • それでもプログラミング言語に関心のある者として「C言語が置き換えられる日」を夢見たい
  • 自ら実装しない理由:
    • AIコーディングの時代に、実装する時間がないという言い訳は通用しなくなってきている
    • 正確には、理論など必要な知識を勉強する時間が足りない