This is a poorly written article that is convoluted and made unnecessarily complex. This is similar to writing an article titled 'tearing apart google search' and then dwelling on HTTP, TCP/IP, routers etc instead of actually talking about how google search works.<p>I was expecting the article to start off by 'tearing apart' the source code, then dig into the algorithms with which diverse formats are rendered, then compare a few popular implementations and finally provide valuable insights, something on the lines of what WalterBright mentioned and the brief discussion it started. If not all this, the minimum I expected was an abridged, annotated source code.<p>This article left me underwhelmed.
In the 1980s, Borland made up for much of the poor code generation of their C compiler by doing the runtime library all in hand-optimized assembler, including printf.<p>What I did (Datalight, Zortech) was make large disk I/O buffers. It gave huge boosts to speed, and very few people cottoned on to that :-)<p>It was a technique I learned from Shal Farley.
<i>Possible trap: Some compilers may recognize the '1' literal used in printf1.c, fold it in to the string, and avoid printf() in both cases. If that happens to you, substitute an expression that must be evaluated.</i><p>Or more "robustly", an expression that comes from external input (such as getchar()). Compilers can be smart enough to evaluate expressions which are constant.<p>This reminds me, I briefly played around with JIT'ing printf() itself --- if you look at it the right way, it's basically a "bytecode" interpreter for the format string. I did get some pretty good performance gains, but it turned out simpler for the project it was intended to go in to just switch to a binary protocol instead of text for output.<p>I also think that writing a (subset of) printf() is a useful exercise for those beginning programming C in general; it's not too difficult (at least if you avoid the floating-point stuff...), but also not too easy either.
Back in the day, I found P.J. Plauger's "The Standard C Library" immensely instructive, as it contains a full implementation of the (then) standard library.<p>Admittedly, the book is more than 25 years old now, but I'm sure it would still make an interesting read:<p><a href="https://www.amazon.com/Standard-C-Library-P-J-Plauger/dp/0131315099/ref=la_B00IP4FPWQ_1_16?s=books&ie=UTF8&qid=1526871663&sr=1-16&refinements=p_82%3AB00IP4FPWQ" rel="nofollow">https://www.amazon.com/Standard-C-Library-P-J-Plauger/dp/013...</a>
> %n - null<p>> %% - complete form<p>Wait, what? %n writes the current number of characters outputted to the int * you specify, while %% just prints a percent sign.
The most fascinating thing about this article for me was the copyright notice at the bottom of the page consisting primarily of asterisks and hash marks.<p>Can anyone explain this to me?
Very, very interesting deep dive. I reminds me of the nand2tetris.org course, which does something very similar (albeit for a toy hardware/OS/language): explain what the heck is going on between a print command and something being written to the screen.<p>In nand2tetris, they work from a hardware simulation that represents memory where a block of that memory determines what the pixels on the screen are set to. Then you write code that can turn the pixels on or off, then a character OS library that converts binary ascii values into a combination of pixel settings that display a character.<p>Then you implement your OS's program loop (the "OS" is based around a one-shot "here a bunch of functions, run from an entry point" that you have to specify each time you turn it on) which has a specified entrypoint from which the rest is called.<p>Obviously, modern systems are a lot faster, but it was a great illustration of what has to happen in between, which this article is doing for real OSes.
How can compilers optimize a printf() call without format strings involved towards a simple puts() call? Sure it would be easy in C++, roughly like<p><pre><code> inline void printf(const char* const s) { puts(s); }
void printf(const char* const s, ...); /* non-trivial implementation */
</code></pre>
but that's not possible in C.