C言語を救うにはABIを守れ
To Save C, We Must Save ABI

C言語のABI(アプリケーション・バイナリ・インターフェース)は、関数の引数や戻り値の受け渡し方法を固定するため、型の変更がバイナリ互換性を壊す。この記事では、long longから__int128_tへの変更が実際にどのようにABIを破壊するかを具体例で示し、C++の名前マングリングとの違いを解説。著者はABI安定性に批判的だが、Cを救うにはABIを守る必要があると主張する。
コンパイラは、あなたに代わって、他のコンパイラや他のマシンと契約を結んでいるのです。これがアプリケーション・バイナリ・インターフェースです。
HNでの議論
177- davemp
> 私たちが文字通り、このような恒久的な決定を下すほど賢くなかったときの遺産的な選択
不必要な傲慢さだ。元のABIの作者たちは十分に賢く、ただ異なる問題に直面していただけだと断言する。
> 私たちの先人たちは、増え続ける圧倒的な負債のない世界に興味がないか、あるいは今すぐその問題に取り組むことを好まないだけだ
記事はこの問題の組織的・社会的側面に言及しているが、その後でこのクソみたいな一言を落としている。
また、私たちの先人たちは悪意も怠惰もなかったと断言できる。彼らはこの提案と同じ問題に直面していたのだ。
私たちのために土台を築いてくれた人々に対するこのような軽蔑の念は見たくない。
- usrnm
有名なC言語のジレンマ:私たちは可能な限りマシンに近づきたいと思っているが、マシンが変わるときには何も変えたくない。
- jdw64
しかし、業界は結局互換性の上で成り立っているので、彼らがそうする理由は理解できる。しかし、互換性が壊れたら、ハードウェアベンダーは滅びないだろうか?PLCや他のハードウェアメーカーを見てみると、彼らは現代的なコーディングすら使っていない。彼らはまだ古いコードで動いている。彼らはそれを「安全で認証されたコード」と言うが、実際にはただのレガシーコードだ。
なぜなら、ハードウェアのプログラマーは、研究者を除いて、ソフトウェアのプログラマーに比べて給料がはるかに低く、労働条件も悪いことが多いからだ。ソフトウェア会社では、コード自体が製品である。しかし製造業では、ソフトウェアは何十億ドルもの価値がある機械に付随するコストとして扱われる。設備やセンサーは更新され続け高価になる一方で、すべてを結びつける人々はコスト削減の対象と見なされる。だからハードウェアのプログラマーは一般的に雇用は安定しているが、給料は高くない。そのような状況で、古いやり方に固執する代わりに新しいことを学ぶように求めると、通常は抵抗に遭う。なぜなら、その学習に対して適切な報酬が支払われていないからだ。
- codeflo
何千もの言葉が結局「intmax_tはABI安定ではない」に帰着する。誰が知らなかっただろうか?(誰もが知っていた。)
- aw1621107
以前の投稿とコメント:
- 2023-06-10、64ポイント、16コメント:(https://news.ycombinator.com/item?id=36249253)
- 2022-03-13、175ポイント、129コメント:(https://news.ycombinator.com/item?id=30660528)
- Panzerschrek
すべてのC ABI問題の根本原因は共有ライブラリだ。それらはほとんど利益をもたらさずに多くの問題を引き起こす。理想的には、どのアプリケーションもそれらを使うべきではない。すべての依存関係は、同じコンパイラと標準ライブラリでソースからコンパイルされるべきだ。システムライブラリも必要ない。システムコールを直接実行できるはずだ。そのようなアプローチでは、ABIの非互換性は起こり得ない。
共有ライブラリはディスクストレージとRAMの両方のスペースを節約できると言う人もいるかもしれない。しかし、そのような節約はそれほど大きくはなく、場合によってはマイナスになることさえある。ライブラリがリンクインされていれば、未使用の機能を破棄したり、多くのライブラリ関数をインライン化したりすることが可能だからだ。
- flohofwoe
タイトルに(2022)と付けるべきだろう。何も変わっていないと思うが(私の知る限り)、空は落ちてこなかった。結局のところ、OSとCPUの組み合わせがABIを定義し、コンパイラツールチェーン(言語を問わず)はそれに従うことしかできない(少なくともオペレーティングシステムと通信したいのであれば)。例えば、いつかオペレーティングシステムが安定したRustフレンドリーなABIを実装したら、Cコンパイラはその慣習に適応しなければならなくなるだろう。
- Panzerschrek
> // 提案: 透過的なエイリアス
> _Alias g = f;
定数関数ポインタを定義すればうまくいくと思う。コンパイラがこのポインタを結果の実行ファイルに保存せず、それを介したすべての呼び出しをソース関数への呼び出しに最適化する限り。