switched txt to md

This commit is contained in:
anihilis 2026-01-20 09:18:07 -08:00
parent 0d4dc438e6
commit f8b6995add

View file

@ -1,213 +0,0 @@
## The mindset shift: C vs C++
In C:
- ❌ No classes, no RAII, no `std::string`
- ✅ **You control memory explicitly**
- ✅ Functions are small, focused, and composable
- ✅ Portability comes from *conditional compilation*
- “Each function returns ownership of dynamically allocated data, and the caller frees it.”*
## Feature macros (`_POSIX_C_SOURCE`)
```c
#define _POSIX_C_SOURCE 200809L
```
### Why this exists
C standard libraries hide some functions unless you *opt in*.
Without it:
* Some systems wont expose those functions
* Youll get mysterious warnings or missing symbols
---
## Headers: what C teaches you here
```c
#include <stdio.h> // printf, FILE
#include <stdlib.h> // malloc, free
#include <string.h> // strlen, strdup
#include <unistd.h> // POSIX functions
```
In C:
* Headers are **contracts**
* If its not included, the compiler assumes *nothing*
**Rule of thumb:**
> If you call a function, its header must be included — no exceptions.
---
## Conditional compilation (`#if defined(...)`)
Example:
```c
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
#endif
```
### What this teaches you
* C has **no runtime reflection**
* Portability happens at **compile time**
* The preprocessor literally removes code before compilation
Think of it as:
```text
“Only compile this code if the OS supports it.”
```
This is how *real* portable C software works (git, curl, openssh).
---
## The most important function in the file
```c
static char *dup_or_unknown(const char *s)
```
### Why this exists
This function enforces a **contract**:
* Every getter:
* returns a valid `char *`
* never returns `NULL`
* always returns heap memory
### Why that matters
It lets `main()` be *simple*:
```c
char *user = get_user();
/* ... */
free(user);
```
No special cases.
No defensive `if (ptr)` checks.
---
## Dynamic allocation patterns (CRITICAL)
Example:
```c
char *buf = malloc(len);
snprintf(buf, len, "...", ...);
return buf;
```
### This is idiomatic C
Rules being followed:
1. Allocate **exactly what you need**
2. Initialize before use
3. Return ownership to the caller
4. Caller must `free()`
Contrast this with C++:
* No destructors
* No smart pointers
* No safety net
---
## Why no global buffers?
You *could* have done:
```c
static char buf[256];
```
But that would:
* Break thread safety
* Break reentrancy
* Make functions non-composable
Dynamic allocation makes your functions:
* Reusable
* Testable
* Library-quality
---
## Reading system information in C
Each platform teaches a lesson:
### Linux
```c
/proc/cpuinfo
/proc/uptime
```
* Text parsing
* Line-by-line scanning
* Defensive string handling
### macOS / BSD
```c
sysctl()
```
* Structured kernel APIs
* Buffer-size negotiation
* Integer & struct-based data
---
## Time handling (classic C pain point)
```c
time_t now = time(NULL);
difftime(now, boottime.tv_sec);
```
Why this matters:
* `time_t` may not be an integer
* You *never* subtract times directly
* `difftime()` handles portability
---
## The `main()` function: clean by design
```c
char *user = get_user();
/* ... */
free(user);
```
Notice:
* No logic
* No parsing
* No platform checks
* No error handling clutter
All complexity lives *outside* `main()`.