3

I've been looking for an answer to this for a couple days, and all of the results I've come up with are about how printf accepts an arbitrary number of arguments.

How does printf write to stdout? What is the most fundamental way to write to a file in C? How do the standard libraries work?

  • 2
  • While this is far too vague/broad/unresearched to be effectively answerable, what you might be after is: At some point it's going to have to call platform-specific code, typically system calls into the OS which are going to be different for every OS the language is implemented on. If you want to know how the system calls are implemented, go read a book about operating systems and how they manage file systems. – Ixrec Oct 9 '15 at 21:56
9

At the lowest possible level from a user program running in some operating system, the libc is making system calls (or syscalls). These are often a single machine instruction (often SYSCALL or SYSENTER) which is given some parameters and which switches the microprocessor to supervisor mode in a controlled way. Then the kernel is processing the parameters and handling the syscall and finally returning to user space. For Linux, you might read its Assembly HowTo and the x86-64 ABI spec.

BTW, you could install Linux and study the source code of some libc. Notice that musl-libc is quite readable.

Of course syscalls (and the protocol to invoke them) are operating system specific. You could read syscalls(2) to get a list of them (for Linux).

printf (and puts) would ultimately invoke the write(2) syscall. For performance reasons, <stdio.h> is buffering.

Notice that printf is standardized in C99 (a programming language standard) but write is standardized in the POSIX Portable Operating System Interface standard (but Microsoft Windows is not POSIX compliant).

Often, printf does not call fputs, but will use some syscall (like  write on Linux). BTW, some implementations (notably the GCC compiler and GNU libc thru its __builtin__snprintf* builtins known by /usr/include/bits/stdio2.h included by <stdio.h>) are able to optimize some simple calls to printf into calls to puts....

6

printf( string, ... ) can be thought of (*1) as internally invoking vfprintf( stdout, string, va_list ) which in turn can be thought of as internally invoking fputs( string, stdout )

The implementation of fputs( string, stdout ) is operating-system specific.

So, (parts of the) standard libraries are rewritten on an operating system by operating system basis to make use of the native facilities provided by the underlying system in order to accomplish their purpose.

(*1) I say "can be thought of" because whether it does precisely that or something else which is equivalent to that is implementation-specific, and none of our concern.

  • Thanks. That answer is helpful, but it also begs more questions. How could fputs be implemented? Is it a call to a function outside C, or is it something that actually could be written in C given a certain platform? – Josh Williams Apr 21 '15 at 17:43
  • 2
    "to make use of the native facilities provided by the underlying system" means that fputs is implemented using a call to a function "outside C". For example, in windows, it invokes the WriteFile method of the Win32 API. Which in turn is most probably also written in C, but now we are talking about an entirely different scope of things. You don't get to write functions of that kind unless you are writing an operating system. – Mike Nakis Apr 21 '15 at 17:48
  • 1
    Thanks, that makes a lot of sense, and it gives me a greater appreciation for the standard library. ;) Cheers! – Josh Williams Apr 21 '15 at 17:50
  • i did this a long time ago for a simple graphics app that could basically draw lines, text, and circles/arcs. there was a concept of points on the 2-dimensional display and a "pen" location that was a point. you can move the pen to any (x,y) coordinate and draw a line to any other (x,y) coordinate. for text, the pen was the base line and there was a primitive putchar() like function that transferred pixels of a bitmap for each ASCII character to the display and then moved the pen to the right by an amount equal to the width of the char. but, like Mike says, it's application specific. – robert bristow-johnson Apr 22 '15 at 2:12
  • 2
    I don't think vfprintf can work in terms of fputs, since printf("%c",0); is defined as causing a single 0 byte to be sent to standard output, and fputs is incapable of sending zero bytes. I would expect printf would use fwrite or an equivalent function; personally I wish there were a vprintf variant that were defined as accepting a void* and a pointer to a function that accepted a void*, a const char*, and number, and would returned int; such a variant could then be used to implement all the other standard forms of printf, and many additional forms besides. – supercat Aug 1 '15 at 20:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.