As other people have explained, printf
doesn't need to know the size of some output buffer ahead of time because it doesn't need to allocate one when writing to a FILE*
stream.
However, you might then wonder: what about functions in the printf
-family that don't write to FILE*
streams? What about, say, the non-standard asprintf
function that returns an allocated string?
The underlying implementation for the printf
family of functions can do a dry-run. That is, it can simulate doing the operation without actually writing to memory and keep track of the number of char
s that it would have written. Once it computes the that number, it then can allocate a buffer of the appropriate size and repeat the operation for real. This is what a caller would do when it needs to allocate a buffer itself, such as when calling snprintf
.
(You also talk about buffered I/O. While printf
can use that, printf
doesn't necessarily know about the buffer itself (and it probably shouldn't). You can think of it as calling fputc
a bunch of times, which then writes the char
to some buffer, flushing it if it's full.)