The most expensive byte in computing
Somebody decided how computers know where text stops. Nobody wrote it down. We have all been quietly paying the invoice since roughly 1969.

Text in a computer is a run of bytes parked next to each other in memory, which we call a string, and something has to mark where the run ends, otherwise the machine keeps cheerfully reading until it finds something it regrets. There are two ways to handle this. Both are obvious. Only one of them is why your bank had a difficult decade.
Option one: write the length at the front. Nine characters coming up. Option two: put a marker at the end and read until you trip over it. The marker won, it is a single byte set to zero, it is called the null terminator, and everything you own is standing on it.
C, the language most of the world's foundations are written in, gets the blame for this, and C is innocent, or at least only an accessory. The switch happened one language earlier. Ken Thompson took BCPL, the Basic Combined Programming Language that Martin Richards wrote at Cambridge in 1967, stripped it down, and called the result B. C is the language after B. Bell Labs, the research arm of the American telephone monopoly and probably the most productive building in the history of computing, was not spending its creative energy on names.
BCPL kept the length in the first byte, which is to say option one was right there, in the family, already working. Thompson kept the shape of the language and threw away the one part of it this article is about.
That ceiling is the good half of the argument. A length held in one byte means a string can be 255 characters long and not one more, ever, in every program, for any purpose, which is completely fine right up until somebody writes a sentence.
Ritchie, who created C and co-created Unix and therefore gets the benefit of the doubt on most things, says ducking that ceiling was the point, and that in his experience keeping a count around was more hassle than a terminator. The assembler for the PDP-11, the fridge-sized minicomputer Unix was built on, already had a directive that laid down text with a zero on the end. An assembler is the thin layer above raw machine code and a directive is a shortcut it offers you, so this was not merely possible, it was the house style of the hardware. The grain of the wood ran that way and he went with it, which is what any reasonable person does on a Tuesday.
I want to be fair here, because the internet enjoys treating this as the stupidest decision ever taken and it is nothing of the sort. It was a trade. Lose instant length, gain unlimited length, on a machine with almost no memory, at a point in history when everybody who could reach your program was in the room with you and would have just asked.
Unfortunately the trade came with a rider nobody read.
One bit of vocabulary and then the fun starts. A buffer is a block of memory a program books in advance, before it knows what is going into it, rather like reserving a table for six and hoping.
Because the end of the text is a fact about the text rather than about the buffer it lives in, nothing in the system knows how big the buffer was. That has to be remembered separately, by a human, every single time anything is copied anywhere, forever. And humans, famously, remember things every single time.
When they do not, the copy sails past the end of the buffer and keeps writing into whatever was parked next to it. Congratulations, you have invented the buffer overflow, which for about thirty years was the single most popular method of breaking into software, and which is less a bug in C than a consequence of geography. Table booked for six, party of nine hundred, and the extra guests are now in the kitchen operating the till.

There is a nastier variant. Sneak a zero byte into the middle of a string and everything after it vanishes, as far as anything reading up to the terminator is concerned. Now one half of your system sees the full name and the other half sees the first four letters, both halves are working exactly as designed, and somebody is logged in as the administrator. This is a real and catalogued category of attack, and it exists entirely because we agreed that text should end whenever it says so.
In 2011 Poul-Henning Kamp wrote the whole thing up in ACM Queue, which is the Association for Computing Machinery's own magazine and therefore not somebody's Medium post, under the title “The Most Expensive One-byte Mistake”. That is a headline you get to write once in a career.
Kamp, for context, is a Danish engineer who wrote Varnish. Varnish is a cache: it keeps a finished copy of a page so the server never builds the same thing twice, which means its entire job is flinging other people's text between buffers at maximum speed. He is not commenting from the stands. He has been mopping this floor for decades.
And then he did the thing that makes the story properly funny. He went looking for the decision. The memo. The note where somebody sat down, put length prefix in one column and terminator in the other, and picked.
He reports finding nothing. No paper trail, and no evidence it was ever a conscious decision at all. The most expensive byte in the history of computing has no receipt.
Which is, honestly, the moral, and it is not that C is bad. This only became a catastrophe because it was reasonable. A sensible man made a sound local call, and then forty years of operating systems, network stacks, file formats and protocols were stacked on top of it, and somewhere in that pile the cost stopped being his and started being everybody's.
All the modern languages carry their lengths properly. They then sit on a runtime, the layer under your language that does the actual talking to the machine, and almost every one of those is written in C. Which is a bit like fitting a very good lock to a tent.
We make a piece with a null terminator on it. It is one character. It is invisible in most typefaces. It is the most consequential punctuation mark of the last fifty years and it does not even turn up in a screenshot.
Where this comes from
- primaryDennis M. Ritchie, “The Development of the C Language”, HOPL-II, 1993That B, not C, dropped BCPL's leading count; that BCPL held the count in the first packed byte; and Ritchie's own two reasons, the 8- or 9-bit ceiling and the inconvenience of maintaining a count.
- primaryPoul-Henning Kamp, “The Most Expensive One-byte Mistake”, ACM Queue 9(7), 2011The title and the venue, the cost accounting, and that he went looking for a record of the decision and reports finding none.
- primaryDEC, “MACRO-11 Assembler Programmer's Manual”, June 1972That the PDP-11 assembler already had a directive laying down zero-terminated text (.ASCIZ), so the convention was the hardware's house style before it was C's.
- primaryAleph One, “Smashing the Stack for Fun and Profit”, Phrack 49, 1996The buffer overflow as a general, repeatable technique rather than a one-off bug. This is the document that made it common knowledge.
- secondaryMITRE, CWE-170: Improper Null TerminationThat the embedded-zero truncation failure is a catalogued weakness class rather than an anecdote.
- secondaryThe Varnish Cache project, Poul-Henning Kamp's notesThat Kamp wrote Varnish, which is why his view on copying text between buffers at speed carries weight.