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•1h ago
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•25m ago
So there was no extension of the functionality over time, all the formats have been supported from day one?
st_goliath•5m ago
The key features that is used here is the '%n' format specified, 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?
As far as I can tell from the PDP11 assembly, Version 7 research Unix (relevant file: /usr/src/libc/stdio/doprnt.s) does not appear to implementation it.
The 4.1BSD version even throws an error, treating it as an invalid format specifier.
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 either System III or System V and through that eventually made it into POSIX?
idorozin•50m ago
This is both impressive and slightly terrifying. Format strings are way more powerful than most people realize.
danbruc•2h ago
marmakoide•1h ago
It was unintentional, but Ken Thompson being Ken Thompson, can't be 100% sure.
danbruc•25m ago
st_goliath•5m ago
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 PDP11 assembly, Version 7 research Unix (relevant file: /usr/src/libc/stdio/doprnt.s) does not appear to implementation it.
The 4.1BSD version even throws an error, treating it as an invalid format specifier.
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 either System III or System V and through that eventually made it into POSIX?