0

I have read that C language does not include instructions for input and for output and that printf, scanf, getchar, putchar are actually functions.

Which are the primitive C language instructions to obtain the function printf , then? Thank you.

3 Answers3

2

If you want to use printf, you have to #include <stdio.h>. That file declares the function.

If you where thinking about how printf is implemented: printf might internally call any other functions and probably goes down to putc (also part of the C runtime) to write out the characters one-by-one. Eventually one of the functions needs to really write the character to the console. How this is done depends on the operating system. On Linux for example printf might internally call the Linux write function. On Windows printf might internally call WriteConsole.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • In an embedded system I've seen `printf` calling `putc`. The implementation of `putc` was left to the developer, i.e. I had to write the `putc` and decide what it should mean in my system. For instance it could be a written to a uart or any other device in the system. – Support Ukraine Feb 05 '15 at 09:58
  • 1
    @nielsen: `putc()` is in itself a function defined by the standard library. If the implementation of `putc()` is left to the developer, that means it does not provide a fully conforming library implementation. That's not a bad thing, mind -- the standard explicitly allows for only a subset of the standard headers being provided ("freestanding" environment). – DevSolar Feb 05 '15 at 09:59
  • @Nielsen I know, printf does not directly call write or WriteConsole. I thought my answer would be easier if I abstract from this. But as you are right I now changed my answer to be more technically correct. – Werner Henze Feb 05 '15 at 10:06
  • @WernerHenze thanks for the answer. This might be a dumb question but when you mention "Linux `write` function...Window `WriteConsole`", are `write` and `WriteConsole` themselves system calls (i.e. invoke kernel routines) or they are just other provided library APIs? – torez233 Dec 21 '21 at 05:59
  • @torez233 From my understanding `write` is a Linux system call and `WriteConsole` is part of the Windows API (library( and internally calls the `NtWriteFile` system call (compare https://stackoverflow.com/a/54228469/1023911). – Werner Henze Dec 21 '21 at 22:31
  • @WernerHenze thanks. For the `write` system call, I'm curious if this call is actually backed by assembly code or still written in C? I know C itself is a pretty low-level language and I'm curious if its API in the end is implemented in assembly then translated into machine code or directly translated into machine code – torez233 Dec 21 '21 at 23:59
1

The function printf is documented here; in fact, it is not part of the C language itself. The language itself does not provide a means for input and output. The function printf is defined in a library, which can be accessed using the compiler directive #include <stdio.h>.

Codor
  • 17,447
  • 9
  • 29
  • 56
  • It should be noted that the standard library is defined in the same document as the rest of the lanugage. – DevSolar Feb 05 '15 at 09:54
1

No programming language provides true "primitives" for I/O. Any I/O "primitives" rely on lower abstraction levels, in this language or another.

I/O, at the lowest level, needs to access hardware. You might be looking at BIOS interrupts, hardware I/O ports, memory-mapped device controlers, or something else entirely, depending on the actual hardware your program is running on.

Because it would be a real burden to cater for all these possibilities in the implementation of the programming language, a hardware abstraction layer is employed. Individual I/O controllers are accessed by hardware drivers, which in turn are controlled by the operating system, which is providing I/O services to the application developer through a defined, abstract API. These may be accessed directly (e.g. by user-space assembly), or wrapped further (e.g. by the implementation of a programming language's interpreter, or standard library functions).

Whether you are looking at "commands" like (bash) echo or (Python) print, or library functions like (Java) System.out.println() or (C) printf() or (C++) std::cout, is just a syntactic detail: Any I/O is going through several layers of abstraction, because it is easier, and because it protects you from all kinds of erroneous or malicious program behaviour.

Those are the "primitives" of the respective language. If you're digging down further, you are leaving the realm of the language, and enter the realm of its implementation.


I once worked on a C library implementation myself. Ownership of the project has passed on since, but basically it worked like this:

  • printf() was implemented by means of vfprintf() (as was, eventually, every function of the *printf() family).
  • vfprintf() used a couple of internal helpers to do the fancy formatting, writing into a buffer.
  • If the buffer needed to be flushed, it was passed to an internal writef() function.
  • this writef() function needed to be implemented differently for each target system. On POSIX, it would call write(). On Win32, it would call WriteFile(). And so on.
DevSolar
  • 67,862
  • 21
  • 134
  • 209