So let me see if I understand the "problems" with printf():
Plus, the format is fixed. You cannot do your own extensions to it (except by prefixing or suffixing format specifiers that look like ordinary printable content).
As a practical and relevant example, take a look at the
format and format_arg function attributes.
If the formatting string is a constant, the compiler may be smart enough to optimize this and generate code that would essentially look like the manual, separate function for each part of the format, but I'm not too sure about that.
I've never seen anything like that at all. What most C compilers do do, however, is change
printf() and
fprintf() calls with a formatting string without conversions into
fputs(), but that's it.
That's the kind of thing I had in mind when I said you'd just reinvented printf.
What an odd way to define "
reinvent".
In that other thread, I explained when formatting strings are useful (localization). It is not about ease of use, it is about providing useful functionality.
If you replace
printf() with an interface that allows you to register a formatting function for a stack trace or processor state dump by just writing it as a function with a specific signature, and then use that formatter as part of your formatting strings everywhere in your firmware/application, is it reinventing?
For one, the printf() formatting specification
cannot support that. The interface you call "reinvented" can support that in plain ANSI/ISO C89. With ISO C99 or later and ELF-compatible object formats, you can make it much more powerful.
I think you just do not think there is any problem in the
printf() interface, and believe it is someone elses job to fix any implementation issues in it if anyone does have a problem. That is a fallacy, because this thread exists: there are problems that cannot be adequately solved within the existing printf() family of functions.
Now, quite a few posts in this thread have pointed out that it is perfectly possible for a printf() to be thread-safe, and that it is not necessary for printf() to require heap. It has also been shown that an implementation printing floating-point numbers can often –– given the formats and values typically printed –– work with very little run-time temporary RAM use (stack!); but, depending on the
numerical value, the conversions can require well over a hundred bytes of stack space.
Let's say you make a variant of printf() that breaks the standard, and
enforces explicit field widths. That is, if you tell it to print say
%+20.9f (±ddddddddd.ddddddddd), and the value cannot fit in that, it will return an error. To make sure your
floats don't exceed the valid range, you do
if (val < -999999999.999999999f) val = -999999999.999999999f; if (val > +999999999.999999999f) val = +999999999.999999999f;and then wonder why you still get errors. (The reason is that 999999999.999999999f is the same as 1000000000.0f, and even the same as 1000000032.0f.)
Thus, the best an implementation could do, is support only a subset of floating-point formatting, specifically those with fixed width (even if it the output is not padded to that width) so that it can clamp any values outside that width to the maximum value (or an overflow string), so that everything it does support, can be done with strict, minimal stack use limits, in a re-entrant, thread-safe manner.
The goddamn annoying thing with that is that you will be reimplementing
printf() from scratch, and instead of fixing the problems and giving the users of the function new ways to solve the problems that lead to this reimplementation in the first place, you'll be just patching issues with spit and bubblegum.
That is much, much worse than "reinventing" (replacing) an interface; I'm talking from experience here. Not only are you not really fixing anything, just papering over the problems that halt the current project –– while doing at least the equivalent amount of work a replacement would need ––, but you will end up having to maintain and tweak it for years to come because none of the users of said bubblegum-fixed-printf() will be happy with the tradeoffs you chose.
It is exactly why developers who are stuck at papering over problems like that, instead of fixing them, are either sociopaths or burn out.
The above should explain why I say "fuck no" to "just fix printf()", and instead reach for something completely different.
printf() is a hammer, a tool. Replacing it with a laser engraver is not reinventing a hammer, it is replacing one tool with another that is designed to be better at the task at hand (if you know what you're doing; not all developers do).