Why don't Standard C Libraries need to be divided into a header and implementation file?

When creating a class in C++, or an equivalent in C with structs, it is always a good idea to divide it into two files: a header file (for declarations) and an implementation file (for actually defining methods and such).

This is done because method-definitions can conflict if they exist in multiple files (and include guards can't prevent that, because macros only exist in the file that they were defined in, and are copied over to files that include them; include guards protect from including the same header multiple times in the same file)

However, it seems as though many of the standard C libraries actually define things. Lets use stdlib.h in C as an example. This library seems to define a method called malloc for allocating memory. But (of course) if I include stdlib.h in multiple files, no method-definitions of malloc seem to conflict.

In other words, if I were to create my own library with my own memory allocation method (assume it is not a macro function) I would have to declare it in mylib.h and actually define it in mylib.c but this does not appear to apply to stdlib.h for some reason.

How does this work? How come Standard C Libraries can do this but user-defined headers (unfortunately, in my opinion) can't?


  • The standard C library has already been compiled into a library, which might be called something like or MSVCRT100.DLL. You can provide this file instead of the *.o or *.obj files that the compiler would generate from your *.c file. The compiler links this runtime library with every program silently and automatically.

    This is how other libraries work, too. If you have the compiled OpenSSL library, you link to the library and #include the header file in your source code to see its interfaces, such as the function names and prototypes. You don't need the other source files that the library was built from.

    You can download the source code to many implementations of the C library, such as GNU libc. The runtime is, in fact, implemented in *.c files, which you can read, modify, recompile and submit patches to the maintainers for, but it's compiled to a shared library ahead of time and your compiler links to that.