Read This! | Picolisp | Picolisp Machine | Pil Sources | Pil Tutorials | Picolisp By Example | Linux | BASH | C-Programmming | Javascipt | Python | Scheme | Operating Systems | AssemblyLanguage | Computer Security | Firewalls | Exploitation | Social Engineering | Metasploit | Emacs | vim | Pharo Smalltalk | Databases | Networking | Machine Learning | Git | Machine Learning | Algorithms | Open Data Science |
C Standard Library
Here is the truth about the C standard library: it is a small, sharp toolkit – I/O, memory, strings, maths, time – that every hosted C program leans on, and its sharpest edges are still the string and unchecked I/O functions. Knowing what is in ISO C versus what your OS adds is half of reading real code.
What it is, in plain words
The C standard library (libc) is defined by the ISO C standard and implemented by projects like glibc (GNU), musl (Void’s default option), dietlibc, and the BSD libcs. Headers you’ll use constantly:
| Header | Role |
|---|---|
<stdio.h> | printf, fopen, fread, snprintf |
<stdlib.h> | malloc, free, atoi, exit, qsort |
<string.h> | strlen, memcpy, memcmp, memset |
<ctype.h> | isdigit, tolower |
<math.h> | sin, sqrt, fma (link -lm on many systems) |
<time.h> | time, strftime, clock |
<stdint.h> / <inttypes.h> | fixed-width integers |
<stdbool.h> | bool (keyword in C23) |
<assert.h> | assert |
<errno.h> | errno values |
<stdarg.h> | variadic helpers |
POSIX and Linux add much more (<unistd.h>, <pthread.h>, <sys/socket.h>…) – useful, but not ISO C.
Why it matters
You can write C without libc (freestanding kernels, some embedded), but almost everything else calls it. Understanding ownership of malloc memory, the difference between size_t and int, and why scanf("%s", buf) is a trap makes you fluent in the language as it’s actually used.
An everyday analogy: a workshop’s communal drawers
Every workshop shares a drawer of tape measures, pencils and utility knives. Libc is that drawer. Some tools (the utility knives – gets, strcpy) will cut you; safer tools (snprintf, memcpy with lengths) do the same job. musl versus glibc is two shops stocking slightly different brands of the same tools.
A hands-on example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void) {
size_t n = 64;
char *buf = malloc(n);
if (!buf) return 1;
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(buf, n, "%Y-%m-%d %H:%M:%S", t);
printf("now: %s\n", buf);
/* Grow a buffer the hard way */
const char *extra = " – Vikix";
size_t need = strlen(buf) + strlen(extra) + 1;
char *p = realloc(buf, need);
if (!p) { free(buf); return 1; }
buf = p;
memcpy(buf + strlen(buf), extra, strlen(extra) + 1);
puts(buf);
free(buf);
return 0;
}
Compile with warnings as errors when you can: gcc -std=c23 -Wall -Wextra -Werror.
Common misconceptions
- “libc is the OS.” It’s a user-space library that calls the OS.
- “All Linuxes share glibc.” Alpine and Void-musl use musl; behaviour differs at the edges (
printfof long doubles, locale, DNS stubs). - "
malloczeroes memory." It doesn’t. Usecallocormemset. - "
errnois always set." It’s only meaningful when a function documents setting it and signals failure. - “ISO C includes networking.” Networking is POSIX / OS-specific.
Freestanding versus hosted
ISO C defines hosted environments (with full libc) and freestanding ones (kernel, bootloader, some embedded) where only a handful of headers are required (<stddef.h>, <limits.h>, <stdint.h>, <stdarg.h>, …) and you provide your own I/O. Knowing which world you’re in stops you from calling printf in a kernel module and wondering why linking fails.
When reading man pages, check whether a function is ISO C, POSIX, or a GNU extension – portability depends on it.
Connections
- C Programming, Strings, Literals.
- Integers, Floats, Characters.
- GCC, objdump.
