Comment by eqvinox

2 days ago

I was very confused by the title, expected someone writing their own printf — i.e. the part that parses the format string, grabs varargs, converts numbers, lines up strings, etc.

I'd have called it "Bare metal puts()" or "Bare metal write()" or something along those lines instead.

(FWIW, FreeBSD's printf() is quite easy to pluck out of its surrounding libc infrastructure and adapt/customize.)

FreeBSD’s printf is my goto, too! It’s indeed enormously simple to pluck out, instantly gives you full-featured printf, and has added features such as dumping memory as hex.

  • Funnily enough we're not even referring to the same one, the hexdump thing is in FreeBSD's kernel printf, I was looking at the userspace one :). Haven't looked at the kernel one myself but nice to hear it's also well-engineered.

    (The problem with '%D' hexdumps is that it breaks compiler format checking… and also 'D' is a length modifier for _Decimal64 starting in ISO C23… that's why our hexdump is hooked in as '%.*pHX' instead [which still gives a warning because %p is not supposed to have a precision, but at least it's not entirely broken.])

Is it? Could you elaborate/provide links to examples of this?

What customization would it support? Say, compared to these options:

https://github.com/eyalroz/printf?tab=readme-ov-file#cmake-o...

  • > Is it? Could you elaborate/provide links to examples of this?

    https://github.com/FRRouting/frr/tree/master/lib/printf

    Disclaimer: my work.

    Customised to support %pHX, %pI4, %pFX, etc. - docs at https://docs.frrouting.org/projects/dev-guide/en/latest/logg... for what these do.

    > What customization would it support?

    I don't understand your question. It's reasonably readable and understandable source code. You edit the source code. That's the customisation?

    > Say, compared to these options: https://github.com/eyalroz/printf?tab=readme-ov-file#cmake-o...

    First, it is customary etiquette to indicate when linking your own code/work.

    Second, that is not a POSIX compatible printf, it lacks support for '%n$' (which is used primarily for localisation). Arguably can make sense to omit for tiny embedded platforms - but then why is there FP support?

    Third, cmake and build options really seem to be overkill for something like this. Copy the code into the target project, edit it. If you use your own printf, you probably need a bunch of other custom stuff anyway.

    Fourth, the output callback is a reasonable idea, but somewhat self-contradictory. You're bringing in your own printf. Just adapt it to your own I/O backend, like libc has FILE*.

    • > You edit the source code. That's the customisation?

      I meant, customization where you don't have to write the customized code yourself, just choose some build options, or at most set preprocessor variables.

      > First, it is customary etiquette to indicate when linking your own code/work.

      You're right, although I was only linking to the table of CMake options. And it's only partially my code, since I'm the maintainer rather than the original author

      > You're bringing in your own printf. Just adapt it to your own I/O backend, like libc has FILE.

      One can always do that, but - with the output callback - you can bring in an already-compiled object, which is sometimes convenient.

      > If you use your own printf, you probably need a bunch of other custom stuff anyway.

      My personal use case (and the reason I adopted the library) was printf deficiencies in CUDA GPU kernels. And - I really needed nothing other than printf functions. Other people just use sprintf to format output of their mostly, or wholly, self-contained functions which write output to buffers and such. Different strokes for different folks etc.

      But - I will definitely check out the link.

      > Second, that is not a POSIX compatible printf, it lacks support for '%n$' (which is used primarily for localisation).*

      That is true. But C99 printf and C++ printf do not support that either. ATM, the aim is completing C99 printf support (when I actually work on the library, which is not that often). So, my priority would be FP denormals and binary FP (with "%a"), before other things.

      > * Arguably can make sense to omit for tiny embedded platforms - but then why is there FP support?*

      It's there because people wanted it / needed it; and so far, there's not been any demand for numbered position specification.

      3 replies →