1. printf may malloc so don't use it in an out of memory situation. Though I think this problem is vanishingly unlikely these days.
2. printf of floats used to require linking to the math library on some platforms (-lm)
3. I am pathetically grateful for nice diagnostics you get when you use the wrong % formatter in more recent C compilers. This used to be a rich source of errors and non-portability.
You can also use __attribute__((format(printf, ...))) for functions of yours that ultimately pass their varargs to a member of the printf family.
It is exceedingly rare for malloc() to give you a recovery chance on failure. Folks are so used to the Linux model of overcommit+OOM killer that almost nobody's code can gracefully deal with memory exhaustion.
> 1. printf may malloc so don't use it in an out of memory situation. Though I think this problem is vanishingly unlikely these days.
I'd like to point out that FreeBSD's printf only does this if:
1. you use a lot of arguments (i.e. a compile-time decision, and quite rare)
2. use wchar_t support (also a compile-time decision and quite rare)
3. the output is to something that buffers/mallocs (i.e. stdio)
4. locale support does it for some reason (I simply haven't checked this)
Which makes it great to use in e.g. crash handlers. It's actually Async-Signal-Safe if you cut out the stdio bits. And it's available under BSD license... and actually a nice read (more on that in a separate post.)
Also, don't use printf in a signal handler for the same reason. Any attempt to malloc or free within a signal handler context runs the risk of a deadlock.
I strongly advise against using either since both are not only non-portable, but also break any compiler support for getting you warnings when you're using it wrong.
This is because they are set when the write function is called. The System V AMD64 ABI specifies that rdi, rsi and rdx are used for the 1st, 2nd and 3rd arguments of a function, perfectly matching the Linux system call ABI. The 5th and 6th also match: r8 and r9, respectively. However, the 4th argument doesn't match: system calls use r10 while System V uses rcx. I wish I knew why.
The x86 `syscall` instruction stores the return address into `rcx` as well as `RFLAGS` into `r11`. These are unconditionally clobbered and thus cannot be saved or used in a `syscall` transition.
Isn't that disassembly a replacement of the call to printf with a call to the write system call? Most compilers have the printf family as builtins to allow removing them from the code entirely: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
I wish there was a book length guide with this kind of tutorial style writing but haven’t found much. Everything I’ve found on Linux is more like a reference resource
This is a good overview of how it all works. On some systems like AmigaOS, there is no libc at all, for example standard input / output is handled by the dos.library in ROM. compiler-specific implementation is delivered as libc.a, which means that only static linking with libc is possible. UNIX®️ software cannot be compiled at all without modification and without having the 3rd party ixemul.library downloaded from "AmiNet" and installed in the LIBS: assign (which usually resolves to SYS:LIBS, which in turn usually resolves to either DF0:LIBS or DH0:LIBS).
“Linux/GNU” is a new one. Not sure if it’s a typo or a troll, but if the latter, it’s a pretty decent troll if such a thing exists? If it’s a typo, geez dude. You’re going to give RMS an aneurysm.
For FRRouting, we decided we want to use Linux kernel style extensions (like "%pI4"), so to get this in a portable way we imported FreeBSD's printf into our code. Since printf() isn't exactly "hot" code getting changed a lot, we considered the maintenance / duplication cost acceptable.
stdio support is completely gone in our copy, WCHAR_SUPPORT is disabled at compile time, locale support is stubbed out/hardcoded to C locale. None of these matter to us. As a result, we can use this printf even in the SEGV handler. (That's only a bonus though, the main reason was extensibility on the format specifiers.)
1. printf may malloc so don't use it in an out of memory situation. Though I think this problem is vanishingly unlikely these days.
2. printf of floats used to require linking to the math library on some platforms (-lm)
3. I am pathetically grateful for nice diagnostics you get when you use the wrong % formatter in more recent C compilers. This used to be a rich source of errors and non-portability.