3 ms·
To back this up, some specific printf issues I've seen in the past: - printf calls malloc - printf calls FPU emulator - platforms differ over whether %p's ou
by to3m 13y ago
To back this up, some specific printf issues I've seen in the past:
- printf calls malloc
- printf calls FPU emulator
- platforms differ over whether %p's output includes a leading 0x
- platforms differ over how you print int64_t/uint64_t
- platforms differ over how you print size_t
- some platforms have almost-ISO-but-not-quite semantics
Additionally, on top of the difficulty of adding extra types in a cross-platform fashion, the printf system is tied to the FILE . FILE s are usually not extensible, and on Windows don't work with sockets.
This is daft, and surprisingly shortsighted (perhaps it's the word "FILE" that causes people to come over all unimaginative?), because you could provide some system like Mac OS X's funopen, and then use fprintf for everything - maybe even replacing snprintf with it! - but functionality like this isn't as widely available as it should be.
Anyway, if you write your own printf, you can fix all of this.
- wezfurlong 13y agoAll of these are factors in our choice for printf here. Another fun one: FILE on Solaris can only be used with file descriptors whose value fits in 8 bits due to an astonishing degree of backwards ABI compatibility. Also on Solaris, printf("%s", NULL) -> crash but on other systems will print "(null)". In our implementation we couldn't solve the frustrating size_t uint64_t stuff without disabling the compile time parameter checking that gcc provides; I value that more than the slight annoyance of PRIu64.
- codehero 13y agoMost of these are all just implementation or platform divergence issues, though what was the FPU emulator issue? That actually seems fundamental to formatted output strategies.
- to3m 13y agoWell, regarding the emulation issue, you've got me there, slightly, because that item was going by what I remember of what my teammate told me in the pub about 12 years ago :) The platform was the Playstation2 and the issue was (as I recall) that the system's FPU supported floats but not doubles, and the supplied libc wasn't fully compatible with the compiler flag that effectively did a typedef float double. (I assume printf was affected because of the traditional varargs promotion rules.) I suspect it was easier to write a new printf than figure out how to rebuild libc, assuming you were even allowed to link the final game to your own libc in the first place... (As for the rest being simply differences between one platform and the next, that's quite true. (And you can usually work around to one degree or another - believe it or not I've worked on a number of multi-platform projects that didn't rewrite printf, though funnily enough every single one had to wrap it.) But then, for what reason does one do this sort of thing, except to remove these differences? You might as well rail against #define stricmp strcasecmp and the like - writing your own printf is just a difference of degree.)
- codehero 13y agoThanks for the response. Hearing a real world example of a type promotion trap was illuminating. I pick on printf in particular because most seasoned programmers consider copying and pasting code a smell, but is accepted for printf and friends.