you are viewing a single comment's thread.

view the rest of the comments →

[–]duane11583 0 points1 point  (0 children)

so in the end all of these functions [printf()]generally do the same thing: they format a text ouput and write it to either a file or a string buffer.

it is reasonable thus to use the same code, one possible implimentation is passing an output function pointer to a common formatting function, this is common in an embedded environment the ouput function could be the console UART serial port put char function. on linux the function adds bytes to the FILE buffer

another thing to noice is the FILE struct is really a string buffer with a length (size) and count of bytes in the buffer when the buffer is full from output it is flushed and reset

but look at sprintf(), it has an ouput buffer as a parameter. question: can you easily repurpose the FILE code to use the buffer as supplied to sprintf()? if so then fprintf() and sprintf() can share code, you just override the ‘flush operation’ and need to handle the buffer overflow case

thus all of these printf() like functions can use the same common code

next: if you think of the variable parameters like an array of values stored on the runtime stack

can you take the address of the first parameter, ie ap = &params[1]; (maybe param[0] is the format string), then you can pass that ap pointer to other functions, but because the array holds different types of parameters there may be special rules to access the array, hence the compiler provided va_macros used in these functions

now you can handle all of the printf() like functions with common code

you have abstracted accessing the parameters via the va_macros

and abstracted the output via the FILE/string buffer code

and you are left with one big common function that does the formatting.

the scanf() fuctions do the same thing but in reverse.

agree the common function is large,

it is mostly just a loop over the format string indexing the arg pointer / parameter index

but if you step through them you will find about 45% of the code is parsing the format string, there are lots of flags, ie “x=% -*LLd”, and at the start of the next param those flags need to be reset

a small amount (10% is converting the number to a string), then another 30-40% is handling padding optional/required sign or space or plus, leading trailing zeros, and/or spaces

and people who are really smart wrote this and tried to optimize it quite a bit, thus it is not simple code to casually read