[HN Gopher] Printf-Tac-Toe
___________________________________________________________________
Printf-Tac-Toe
Author : carlos-menezes
Score : 115 points
Date : 2026-03-08 12:01 UTC (4 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| danbruc wrote:
| How did we end up with printf - within a loop - being Turing-
| complete? Was it designed that way from the beginning? Were new
| features added over time until we got there?
| marmakoide wrote:
| Having something Turing-complete is surprisingly easy, and it
| hides everywhere. The repository have a small document that
| explains how you can use printf() as a computer : it can
| performs additions, logical union and negation, which is
| enough.
|
| It was unintentional, but Ken Thompson being Ken Thompson,
| can't be 100% sure.
| danbruc wrote:
| So there was no extension of the functionality over time, all
| the formats have been supported from day one?
| st_goliath wrote:
| The key features that is used here is the '%n' format
| specifier, that fetches a pointer as the next argument, and
| writes a character count back.
|
| There is actually an interesting question here: was '%n'
| always in printf, or was it added at one point?
|
| I took a cursory look at some old Unix source archives at
| TUHS: https://www.tuhs.org/cgi-bin/utree.pl
|
| As far as I can tell from the PDP-11 assembly, Version 7
| research Unix (relevant file: /usr/src/libc/stdio/doprnt.s)
| does _not_ appear to implement it.
|
| The 4.1BSD version of that file even _explicitly throws an
| error_ , treating it as an invalid format specifier.
|
| The implementation in a System III archive looks
| suspiciously similar to the BSD one, also throwing an
| error.
|
| Only in a System V R4 archive (relevant file:
| svr4/ucblib/libc/port/stdio/doprnt.c) I found an
| implementation of "%n" that works as expected.
|
| I guess it was added at some point to System V and through
| that eventually made it into POSIX?
| sltkr wrote:
| I think it was first introduced in 4.3 BSD Tahoe
| (released June 15, 1988): https://www.tuhs.org/cgi-
| bin/utree.pl?file=4.3BSD-Tahoe/usr/...
|
| This was an update to the earlier 4.3 BSD (1986) which
| still implemented printf() in VAX assembly instead, and
| doesn't support the %n feature.
|
| So %n may have originally been implemented in 4.3 BSD
| Tahoe and made its way into SVR4 subsequently.
| gwern wrote:
| List of examples: https://gwern.net/turing-complete
|
| It was probably unintentional, yeah, I don't recall any
| mentions of early printf being overloaded to do stuff, nor is
| it clear why you would do that since you're using it in a
| much more convenient Turing-complete language already (C).
| idorozin wrote:
| This is both impressive and slightly terrifying. Format strings
| are way more powerful than most people realize.
| JKCalhoun wrote:
| Contestant: "I'll take _My Dirty Programming Secrets_ for 100,
| Alex. "
|
| Alex: "Its primary purpose is to serve as The One True Debugger."
|
| (It has certainly served me well.)
| LoganDark wrote:
| To be fair, this is actually `scanf` and `printf` in a loop. The
| `scanf` is buried in the `arg` define.
| binaryturtle wrote:
| That's the content why I check HN! :)
| ivanjermakov wrote:
| No surprise Log4J attack was that big. Amount of logic one can
| fit into text formatting is immense.
| mrngm wrote:
| [2020], and written for IOCCC: The International Obfuscated C
| Code Contest.
|
| This was awarded "Best of Show - abuse of libc" at the time[0].
| See also the judges' remarks[1]:
|
| _This program consists of a single printf(3) statement wrapped
| in a while loop. You would not think that this would amount to
| much, but you would be very, very wrong. A clue to what is
| happening and how this works is encoded in the ASCII art of the
| program source._
|
| [0] https://www.ioccc.org/2020/index.html
|
| [1] https://www.ioccc.org/2020/carlini/index.html
___________________________________________________________________
(page generated 2026-03-12 23:01 UTC)