プログラミング
C言語の柔軟な整数サイズは設計ミスではなかった
C's Flexible Integer Sizes Were Not a Design Mistake (pikuma.com)
要約
C言語の整数型(intなど)のサイズが固定されていないのは、設計ミスではなく、多様なコンピューターアーキテクチャ間での移植性を確保するための意図的な設計であった。初期のコンピューターはバイトサイズやワードサイズが統一されておらず、C言語はこれらの環境で効率的に動作するために、そのマシンの「自然な」整数サイズを採用した。現代ではSTDINT.Hヘッダーで固定サイズ整数が利用可能だが、C言語の柔軟性は当時の移植性要求に応えるための重要な機能だった。
全文翻訳
C言語の柔軟な整数サイズは設計ミスではなかった
ワードサイズ、奇妙なマシン、そしてintが32ビットを意味しなかった理由。
C言語の柔軟な整数型は設計ミスではありませんでした。それらは、12ビット、18ビット、36ビット、60ビットのコンピューターが混在する世界で、言語が移植性を達成する方法でした。
Gustavo Pezzi
2026年9月25日 · 15分読書
私たちは学校で多くのレトロマシンや古いゲームコンソールを扱っているため、多くの開発者がCプログラミング言語を学ぶ際の最初の相談窓口になることは珍しくありません。私たちの学生の多くは、Python、JavaScript、Java、C#、Swiftなどの言語から来ています。初心者が、自分の主要言語で当然だと思っていた多くの側面が、C言語では必ずしもそうではないことに気づくまで、それほど時間はかかりません。私たちはしばしば、「この変数はメモリの何ビットを占めるのか?」「この構造体のパディングは?」「このフィールドはRAMで正しくアラインメントされているか?」といった疑問に直面します。
整数は32ビットではない
C言語の初心者にとって、sizeof演算子の使い方を学び、意味を理解することも、もう一つの通過儀礼です。intのsizeofを尋ねたときにプログラムが4と出力されるのを見るのは、ほとんどの現代のマシンでは、符号付き整数が確かにメモリ上で4バイトを占めることを考えると、もっともらしいことです。
sizeof int: 4バイト
残念ながら、私がコーディングを始めた頃、sizeof(int)を尋ねると、私の古い386マシンは2バイトと出力したと、学生に伝えなければなりません!
sizeof int: 2バイト
そして、ここでC言語のネイティブな整数型が固定サイズを持たないという議論が始まります。char、int、short、longといった言語型は、メモリ上で何バイトを占めるかという保証がありません。通常、コードで固定サイズを望むため、学生にはSTDINT.Hヘッダーを使用して、以下のような実際の固定サイズ型を利用することを推奨しています。
int8_t: 正確に8ビットの符号付き整数
uint8_t: 正確に8ビットの符号なし整数
int16_t: 正確に16ビットの符号付き整数
uint16_t: 正確に16ビットの符号なし整数
int32_t: 正確に32ビットの符号付き整数
uint32_t: 正確に32ビットの符号なし整数
など。
ヘッダー<STDINT.H>はC99標準(1999年発行)の一部として導入され、コンパイラやコンパイル対象のマシンアーキテクチャに関わらず、プログラマーが変数が正確なバイト数を占めるように宣言することを保証するのに役立ちます。
非固定整数サイズは設計ミスか?
プログラミング界でよく聞かれる意見として、C言語のプラットフォーム依存の整数型は設計ミスだったというものがあります。公平に言えば、これは間違っていません。現代のシステムでC言語を使用するほとんどのプログラマーは、まさにそう主張するでしょう。あるマシンではintは16ビット、別のマシンでは32ビット、longはLinuxでは64ビットだが64ビットWindowsでは32ビット、そしてこれらすべてが数十年にわたる移植性バグの原因となっています。では、今日ほとんどすべてのCPUが8ビット、16ビット、32ビット、64ビットの算術演算を処理する64ビットマシンであるにもかかわらず…なぜC言語は最初からサイズを固定しなかったのでしょうか?
これは基本的に、2020年代の状況で1970年代のデザイン上の決定を判断しようとしているようなものです!
C言語は、非常に異なるコンピューターアーキテクチャに効率的にマッピングできる、ポータブルなシステムプログラミング言語として構築されました。柔軟な型サイズは見落としではなく、C言語がその移植性を達成した方法でした。C言語の「移植性」の目標は、Javaの「一度書けば、どこでも実行できる」という移植性の約束とは異なる意味を持っていたことを覚えておいてください。そして、その理由を理解するには、C言語が設計された当時の「コンピューター」が何を意味していたかを思い出す必要があります。
8ビットバイト以前の世界
今日、私たちは多くのことを当然のことと思っています。あなたが触れるほとんどすべてのマシンは、8ビットバイト、バイトアドレス可能なメモリ、32ビットまたは64ビットレジスタ、2の補数整数、フラットで標準的なメモリモデルを備えています。1960年代から70年代にかけて、これらは何も保証されていませんでした。業界は収束しておらず、マシンのワードサイズは様々でした。
マシンワードサイズ
注記
DEC PDP-8
12ビット
非常に人気のあるミニコンピューター
DEC PDP-7
18ビット
UNIXが生まれた場所、アセンブリ言語で
DEC PDP-11
16ビット
バイトアドレス可能。C言語が育った場所
DEC PDP-10 / DECSYSTEM-20
36ビット
文字はしばしば7ビットまたは9ビットでパックされていました
Honeywell 6000シリーズ
36ビット
9ビット文字。初期のC言語のターゲット
UNIVAC 1100 / Unisys 2200
36ビット
1の補数算術、9ビット文字。今日でもC言語コンパイラがあります
IBM 7090 / 7094
36ビット
6ビット文字コード
SDS 940, ICL 1900, Harris
24ビット
ICLは6ビット文字を使用
Burroughs B5000ファミリー
48ビット
タグ付き、スタック指向アーキテクチャ
CDC 6600
60ビット
6ビット文字、バイトアドレス指定なし
Cray-1
64ビット
ワードアドレス指定。C言語では、short、int、longはすべて64ビットになる可能性がありました
Data General Nova
16ビット
ワードアドレス指定。バイトポインタはワードポインタとは異なる表現を持っていました
Intel 8086
16ビット
セグメント化されたメモリ。ニアポインタとファポインタ
DECのPDP-8ミニコンピューター
文字も一貫性がありませんでした。6ビット文字セット、7ビットASCII、36ビットマシン上の9ビットバイト、IBMメインフレーム上のEBCDICがありました。負の数は2の補数、1の補数、または符号・絶対値で格納できました。一部のマシンは個々のバイトをアドレス指定できました。他のマシンはワード全体しかアドレス指定できなかったため、「文字へのポインタ」はワードアドレスとオフセットの組み合わせである必要がありました。効率的かつこれらのマシン間で移植可能であることを望む言語は、あまり多くを仮定できませんでした。
C言語の型はどこから来たのか
C言語の整数哲学は、その祖先を見るとより理解しやすくなります。BCPL(Martin Richards、1967年)とB(Ken Thompson、1969年頃)は型のない言語でした。値の種類は1つだけでした:マシンワード。変数はワードを保持しました。適用する演算子によって、整数、アドレス、またはビットパターンとして扱うことができました。これらの言語がターゲットとしていたワードアドレス指定のマシンでは、それはエレガントで効率的でした。
その後、ベル研究所はPDP-11を手に入れました。PDP-11はバイトアドレス指定で、16ビットワードを持ち、浮動小数点ハードウェアを搭載しようとしていました。Dennis Ritchieは、The Development of the C Language(1993年)で、B言語の「すべてはワードである」というモデルがそのマシンにどれほど合わなかったかを説明しています。文字の扱いは不器用で、ポインタはワードとバイトアドレスの間でスケーリングする必要があり、浮動小数点値はワードに収まりませんでした。
Dennis RitchieとKen Thompsonがベル研究所でPDP-11/20で作業している様子。
C言語の型システムは、その不一致を修正するために作成されました。charはバイトを提供しました。intはBCPLのワードの精神、つまりマシンの自然な整数を維持しました。その考え方は言語の一部となりました。今日でも、C標準(C11 §6.2.5)は次のように述べています:「プレーンなintオブジェクトは、実行環境のアーキテクチャが示唆する自然なサイズを持ちます。」これは意図的な設計ステートメントです。intは決して「32ビット」を意味するものではありませんでした。それは「そのマシンが最も速く、最も快適に扱えるもの」を意味していました。
C言語はPDP-11を脱出する
本当の試練は、1977年と1978年に訪れました。RitchieとSteve Johnsonは、PDP-11とはかなり異なる32ビットマシンであるInterdata 8/32にUNIXとC言語を移植しました。彼らはPortability of C Programs and the UNIX System(Bell System Technical Journal、1978年)でそれについて書いています。ほぼ同時期に、JohnsonのPortable C Compiler(pcc)は、C言語を新しいアーキテクチャにリターゲットすることを実用的なものにし、C言語は幅広いハードウェアに広まりました。
The C Programming Languageの初版(Kernighan & Ritchie、1978年)には、私がよく指摘する表が含まれています。それは、C言語がすでに動作していた4つのマシンでの型サイズをリストアップしています。
タイプ
DEC PDP-11
Honeywell 6000
IBM 370
Interdata 8/32
char
8ビット
9ビット
8ビット
8ビット
short
16
36
16
16
int
16
36
32
32
long
32
36
32
32
float
32
36
32
32
double
64
72
64
64
1978年、C言語はすでに16ビットint、32ビットint、36ビットintのマシンで動作しており、8ビットと9ビットのcharがありました。柔軟なサイズは最初から存在し、機能していました。同じ言語、そして大部分は同じプログラムが、これらのすべてのマシンでネイティブかつ効率的に動作しました。
なぜ柔軟なサイズが役立ったのか
もしC言語が、多くの現代の言語のように、intを正確に32ビット、2の補数、オーバーフロー時にラップアラウンドするように要求していたらどうなっていたでしょうか?それがどれほどのコストがかかったかを見てみましょう。
1. 16ビットマシン(PDP-11)上では