routine update, no changes
This commit is contained in:
parent
f458b73fd5
commit
0d4dc438e6
1 changed files with 15 additions and 86 deletions
|
|
@ -1,28 +1,15 @@
|
||||||
Perfect — let’s switch hats from *“just making it work”* to *“learning C properly”*.
|
## The mindset shift: C vs C++
|
||||||
I’ll explain **how to read and think about this file**, not just what it does.
|
|
||||||
|
|
||||||
I’ll reference the structure you now have in the file and explain the *C concepts* behind each part.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1️⃣ The mindset shift: C vs C++
|
|
||||||
|
|
||||||
In C:
|
In C:
|
||||||
|
|
||||||
* ❌ No classes, no RAII, no `std::string`
|
- ❌ No classes, no RAII, no `std::string`
|
||||||
* ✅ **You control memory explicitly**
|
- ✅ **You control memory explicitly**
|
||||||
* ✅ Functions are small, focused, and composable
|
- ✅ Functions are small, focused, and composable
|
||||||
* ✅ Portability comes from *conditional compilation*
|
- ✅ Portability comes from *conditional compilation*
|
||||||
|
|
||||||
Your program follows a **very idiomatic C pattern**:
|
- “Each function returns ownership of dynamically allocated data, and the caller frees it.”*
|
||||||
|
|
||||||
> *“Each function returns ownership of dynamically allocated data, and the caller frees it.”*
|
## Feature macros (`_POSIX_C_SOURCE`)
|
||||||
|
|
||||||
That’s a **huge** C concept to internalize.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2️⃣ Feature macros (`_POSIX_C_SOURCE`)
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
@ -32,21 +19,14 @@ That’s a **huge** C concept to internalize.
|
||||||
|
|
||||||
C standard libraries hide some functions unless you *opt in*.
|
C standard libraries hide some functions unless you *opt in*.
|
||||||
|
|
||||||
This line tells the compiler:
|
|
||||||
|
|
||||||
> “I want modern POSIX features like `strdup`, `gethostname`, `sysconf`.”
|
|
||||||
|
|
||||||
Without it:
|
Without it:
|
||||||
|
|
||||||
* Some systems won’t expose those functions
|
* Some systems won’t expose those functions
|
||||||
* You’ll get mysterious warnings or missing symbols
|
* You’ll get mysterious warnings or missing symbols
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 In C, *what functions exist* depends on feature macros.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3️⃣ Headers: what C teaches you here
|
## Headers: what C teaches you here
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include <stdio.h> // printf, FILE
|
#include <stdio.h> // printf, FILE
|
||||||
|
|
@ -66,7 +46,7 @@ In C:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4️⃣ Conditional compilation (`#if defined(...)`)
|
## Conditional compilation (`#if defined(...)`)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
@ -92,7 +72,7 @@ This is how *real* portable C software works (git, curl, openssh).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5️⃣ The most important function in the file
|
## The most important function in the file
|
||||||
|
|
||||||
```c
|
```c
|
||||||
static char *dup_or_unknown(const char *s)
|
static char *dup_or_unknown(const char *s)
|
||||||
|
|
@ -121,12 +101,9 @@ free(user);
|
||||||
No special cases.
|
No special cases.
|
||||||
No defensive `if (ptr)` checks.
|
No defensive `if (ptr)` checks.
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 In C, helper functions enforce invariants so callers stay clean.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6️⃣ Dynamic allocation patterns (CRITICAL)
|
## Dynamic allocation patterns (CRITICAL)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
@ -151,12 +128,9 @@ Contrast this with C++:
|
||||||
* No smart pointers
|
* No smart pointers
|
||||||
* No safety net
|
* No safety net
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 In C, *ownership is a social contract*, not a language feature.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7️⃣ Why no global buffers?
|
## Why no global buffers?
|
||||||
|
|
||||||
You *could* have done:
|
You *could* have done:
|
||||||
|
|
||||||
|
|
@ -176,12 +150,9 @@ Dynamic allocation makes your functions:
|
||||||
* Testable
|
* Testable
|
||||||
* Library-quality
|
* Library-quality
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 Globals are easy — dynamic ownership is correct.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8️⃣ Reading system information in C
|
## Reading system information in C
|
||||||
|
|
||||||
Each platform teaches a lesson:
|
Each platform teaches a lesson:
|
||||||
|
|
||||||
|
|
@ -206,12 +177,9 @@ sysctl()
|
||||||
* Buffer-size negotiation
|
* Buffer-size negotiation
|
||||||
* Integer & struct-based data
|
* Integer & struct-based data
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 C doesn’t abstract the OS — it exposes it.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9️⃣ Time handling (classic C pain point)
|
## Time handling (classic C pain point)
|
||||||
|
|
||||||
```c
|
```c
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
@ -224,12 +192,9 @@ Why this matters:
|
||||||
* You *never* subtract times directly
|
* You *never* subtract times directly
|
||||||
* `difftime()` handles portability
|
* `difftime()` handles portability
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 In C, use the standard library *exactly as intended*.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔟 The `main()` function: clean by design
|
## The `main()` function: clean by design
|
||||||
|
|
||||||
```c
|
```c
|
||||||
char *user = get_user();
|
char *user = get_user();
|
||||||
|
|
@ -246,39 +211,3 @@ Notice:
|
||||||
|
|
||||||
All complexity lives *outside* `main()`.
|
All complexity lives *outside* `main()`.
|
||||||
|
|
||||||
**Lesson:**
|
|
||||||
👉 In C, `main()` should read like a script.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1️⃣1️⃣ What this code teaches you overall
|
|
||||||
|
|
||||||
You’ve learned:
|
|
||||||
|
|
||||||
* ✅ How C handles memory *explicitly*
|
|
||||||
* ✅ How portability really works
|
|
||||||
* ✅ How to design safe APIs in unsafe languages
|
|
||||||
* ✅ How Unix exposes system information
|
|
||||||
* ✅ How real-world C programs are structured
|
|
||||||
|
|
||||||
This is **not beginner C** — this is *professional-grade foundational C*.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## If you want to go deeper next
|
|
||||||
|
|
||||||
From a learning perspective, great next steps would be:
|
|
||||||
|
|
||||||
* 🔹 Splitting into `.h` / `.c`
|
|
||||||
* 🔹 Writing your own `string_builder`
|
|
||||||
* 🔹 Adding error-return variants (`int get_x(char **out)`)
|
|
||||||
* 🔹 Making this a reusable library
|
|
||||||
* 🔹 Running it under `valgrind` and analyzing output
|
|
||||||
|
|
||||||
If you want, I can:
|
|
||||||
|
|
||||||
* Rewrite one function *line by line* explaining *every character*
|
|
||||||
* Or turn this into a **guided C learning project**
|
|
||||||
|
|
||||||
Just tell me how deep you want to go — you’re asking exactly the right questions 👏
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue