I've heard while looking at different C implementations that any system that hopes to implement C must minimally include certain libraries, stdarg.h etc. My question is why this is, it can't be that the C library is not Turing complete without some headers, and since the headers have been written it must be true that I could write them myself. Why, then, is it not permissible to have a C implementation consisting of just a compiler+linker toolchain? (of course, in this case interacting with the OS would require inline assembly or linked assembly code as well as knowledge of the system's syscalls etc., but that doesn't mean that C can't be written, does it?)
-
6Because you still have to interface with the OS, and standard libraries provide an easy and portable way of doing that. Turing complete != useful (see also: brainfuck). Also note that most standard libraries for C are written in C. – Colonel Thirty Two Jan 18 '16 at 18:19
-
9you seem to confuse 'turing complete' with 'writing software that does useful stuff' – pm100 Jan 18 '16 at 18:19
-
1Language and library are two different things, but the C standard mandates a compliant implementation to actually implement both. – Macmade Jan 18 '16 at 18:19
-
1If you have a C compiler...which can't compile existing C code...is it really a C compiler? – Bob Jarvis - Слава Україні Jan 18 '16 at 18:20
-
C code can be compiled without any headers or libraries, provided it does not reference them. But you won't be able to provide input (apart from initialised variables) or get any output. To save you the trouble of writing code to use OS services, that's why the libraries are used. – Weather Vane Jan 18 '16 at 18:22
-
6A full C implementation provides a *hosted C environment*. In those, the preprocessor macro `__STDC_HOSTED__` will be defined to `1`. You can also have, or use, a *freestanding C environment*, where you do not have the C standard library available (unless you implement the standard functions yourself). Freestanding C is commonly used for kernel development, and for embedded systems and microcontrollers (although some kind of libraries are often provided by manufacturers for the latter). In other words, the question itself makes incorrect assumptions: it is permitted. – Nominal Animal Jan 18 '16 at 18:39
-
1Nominal Animal answered my question perfectly. I think some of you were confused by my wording: I immediately dismissed that the C language is not turing complete without libraries, because that would imply that those libraries couldn't be written in C. – ocket8888 Jan 18 '16 at 18:56
-
Your last assumption is false. You can have a language that is not TC but can generate a T-complete language (the grammar that express a Turing machine)... – Jean-Baptiste Yunès Jan 18 '16 at 19:50
-
1@Macmade: That is really true. A freestanding implementation need not provide the library, but only few target-specific headers. – too honest for this site Jan 18 '16 at 19:52
-
1whoa wait, what target-specific headers? – ocket8888 Jan 18 '16 at 20:14
-
1@NominalAnimal: Many vendor-provided libraries are actually rubbish. They often just add additional complexity without benefit. The only useful part of that are the headers for peripheral hardware-registers. And those are (too) often buggy, too. – too honest for this site Jan 18 '16 at 20:15
-
1@user: Please just read the standard! – too honest for this site Jan 18 '16 at 20:15
-
1@Olaf: Completely agreed; that's why I wrote 'some kind of libraries'. – Nominal Animal Jan 18 '16 at 21:01
2 Answers
You confuse a property of the programming language, i.e. the language itself with additional features mandated by the standard.
"Turing complete" is just about the language itself; basically if you can use it to solve a certain class of problems (for a more exact definition, please see Wikipedia for a starter(!) ). That is quite an abstract concept and does not include any libraries. Basically, if you use such libraries, you just have to be able to write those libraries in the language itself. This is true for the C language.
About the libraries required: Your premise is wrong. C very well allows to omit the libraries themselves. That is the difference between a hosted (full libraries) and a freestanding (few target-specific headers, but no generated code). See 4p6.
The few headers are normally part of the compiler itself. They basically provide some typedef
s and #define
d constants, e.g. the range of the integer types (limits.h
) and types of guaranteed minimum width (stdint.h
, often also fixed-width types). stddef.h
e.g. provides size_t
and NULL
.
While you do not need to use those headers, they already allow writing portable code for the program logic. Just see them as part of the language itself, tailored to the target.
The gcc C compiler, for instance actually is a freestanding implementation: It only provides the required headers, but not the standard library. Instead, it relies on the system library, which is e.g. glibc on Linux.
Note: Generally it is a bad idea to re-invent the wheel. So if you are on a hosted environment (i.e. full-grown OS), you should use the features available. Otherwise you might run into trouble, as these e.g. mightr provide additional functions not directly seen by your code. E.g. debugging or system/user-wide configuration like localisation support. Also debugging support might depend on you using the standard library, e.g. valgrind. Replacing memory allocation with your own code at least makes this much more difficult.
Not to mention maintainability. Not just others will understand your code easier if you use the standard names&semantics, but also yourself - just wait some years and try understanding your old code.
OTOH, if you are on a bare-metal embedded system, there is actually little use of most features the standard library. Including e.g. printf
or scnaf
just bloats your firmware, often without any actual use. For such systems, there are stripped-down libraries (e.g. newlib
) which may be not completely compliant or allow to omit certain costly features, e.g. floating point conversion or the math lib. Still you only should use them iff you really need many of their features. And sometimes there is a middle way, but that requires some knowledge about the dependencies of the library.

- 12,050
- 4
- 30
- 52
-
1Thank you, this is perfect. On the subject of the target-specific headers, can you tell me where to find documentation for dummies that will tell me exactly what these are specified to contain? http://eli-project.sourceforge.net/c_html/c.html#s1 is where I was looking, but I don't see any of these headers here. – ocket8888 Jan 18 '16 at 20:38
-
1@user3777314: Please see the C standard (I provided a link to the final draft in the text; that is very much the same as the final version). If you are really interested in deeper research, **that** is the resource you should study. Note, if the answer is "perfect" for you, feel free to also upvote ;-) – too honest for this site Jan 18 '16 at 20:43
-
1
Two reasons: compatibility and system interaction.
If you don't implement the whole C standard library, then code other people write won't work. Even the most basic C program uses library calls.
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
Without an agreed upon and fully implemented stdio.h
that program will not run because the compiler doesn't know what printf()
means.
Then there's system interaction. C has been called "portable assembly". This is because different computing environments do things differently, but C takes are of that for you (well, some of it). You can't write a portable stdio.h
in assembly without losing your mind. But its more than that. Each C header file protects you from something that each environment does (or used to) do very differently.
stdlib.h
shields you from differing memory models and process control.stdio.h
shields you from differing IO systems.math.h
shields you from differing floating point implementations.limits.h
shields you from differing data sizes.locale.h
shields you from differing locales.
The C libraries provide a standard API that each environment can write to. When C is ported to a new environment, that environment is responsible for implementing those libraries according to the particulars of that system. You don't have to do that.
Nowadays we live in a much more homogeneous environment than when C was developed, but most of the C standard library still protects you from basic differences in how operating systems and hardware do things.
It didn't always used to be this way. An example that comes to mind is the hell of running a game on DOS. There was no standard interface to the sound and video card (if you had them). Each program had to ship drivers for each sound and video card they supported. If yours wasn't in there, sorry. If their driver was buggy, sorry.
Programming without the C standard library is kind of like that, but far far worse.

- 153,029
- 25
- 195
- 336
-
1This is a good answer, but it wasn't what I was looking for. In short: what if I don't care about other people? sounds mean, but what I mean by that is C code doesn't need to be portable (or simple) to be written. I like NominalAnimal's response as a more direct answer. But thanks for the well-written answer! – ocket8888 Jan 18 '16 at 19:02
-
1@user3777314 That would be the whole middle part of the answer. Without the C standard library you can only allocate stack memory (no `malloc`). You cannot see your program's output (no `printf`). You cannot read files (no `fopen`). Sure, you could write all this in assembly for your particular machine, but the C library authors have already done that better than you can. And then that code is welded to that piece of hardware and OS; upgrading either will probably break the code. You *can* do it, and it was done before things like C became standard, but it's horrifying. – Schwern Jan 18 '16 at 19:06
-
2The answer is wrong. A freestanding implementation & environment is very well compliant by just providing few target-specific headers, but no (code) library. You can do very useful things in C without them. You just have to directly access hardware registers or use system calls. Actually gcc itself is such an implementation, as it does not provide the standard library, but relies on the runtime environment to provide it (e.g. GNU libc or newlib). – too honest for this site Jan 18 '16 at 19:56
-
1@Olaf Yes, you can get things done in a very painful and non portable fashion. You'd only do this if you must, like when writing a compiler or porting the standard library. The question was why a C implementation must include the standard libraries, not whether you can get things done without them. – Schwern Jan 18 '16 at 20:02
-
1@Schwern: You have never worked with embedded systems, right? Most implementations for such systems are freestanding implementations and the targets do not provide the standard library - for good reason. If you don't have mass storage or console IO, there is "little" need for streams, etc. Btw: when writing a compiler itself, the standard library is actually very useful. How else would you read/write files or provide user output? About the question and your answer: you did not even correct the wrong premise of the question. The C standard very well allows a compliant impl.&environm. omit it. – too honest for this site Jan 18 '16 at 20:09
-
@Olaf You're right, I have not. Write up an answer about that environment. – Schwern Jan 18 '16 at 20:10
-
1@Olaf is correct, I don't care if the code is portable or whether or not it's painful to write. I can, in fact see the output of my program, but only if I know the system it's being run on before I write it, using direct syscalls. The only thing I care about is if C can be written (in a way that could produce any modern binary, even if only on one system) without any libraries. – ocket8888 Jan 18 '16 at 20:12
-
@user3777314 You should edit your question to clarify what you're asking. – Schwern Jan 18 '16 at 20:19
-
1"Why, then, is it not permissible to have a C implementation consisting of just a compiler+linker toolchain? (of course, in this case interacting with the OS would require inline assembly or linked assembly code as well as knowledge of the system's syscalls etc., but that doesn't mean that C can't be written, does it?)" I feel like that addresses the issue, but if you have a suggestion on how to word it better I"d be happy to hear it. – ocket8888 Jan 18 '16 at 20:26
-
@user3777314 If you edit your question to focus on the question, that will help. Right now your question focuses on why C is how it is. Maybe "is it possible to code C without the standard library, and when/why would you do this?" – Schwern Jan 18 '16 at 22:00