Contracts for C
C’s Conservatism vs Language Evolution
- Several comments argue C should stay small and stable, unlike Java, C#, or modern C++, which have grown complex.
- Others counter that most other ecosystems evolved in response to developer demand; resistance to change in C has pushed people toward C++, Rust, Zig, etc.
- There’s disagreement about how representative current C users are: some say “most C programmers don’t want new features,” others call this survivorship bias because many who wanted more features already left.
Contracts as a Feature for C
- Some see contracts as a useful, opt‑in way to improve existing C codebases without rewrites; those uninterested can ignore them.
- Others argue C already has
assertand that contracts add syntax and complexity without solving core issues like memory safety, slices/spans, or a stronger standard library. - There’s prior art: Eiffel, Ada/SPARK, D, and tools like Frama‑C and “cake” are mentioned as richer or more formal contract systems.
Undefined Behavior and unreachable()
- The proposed macro‑based contracts use
unreachable()(C23) to turn contract violations into undefined behavior. - Critics say this is conceptually wrong: contracts should allow compilers to prove properties or produce diagnostics, not convert recoverable failures into UB that can be reordered or optimized away.
- Some defend explicit UB markers as useful: they document impossible paths and help optimizers and static analyzers, but concede they’re not reliable runtime checks.
Panics vs Error Handling
- One subthread questions whether contracts that abort (or “panic”) are better than silently hitting UB.
- Pro‑panic side: failing fast near the bug with a clear message is safer and easier to debug than memory corruption.
- Anti‑panic side: in many domains (embedded, real‑time, critical systems), crashing is unacceptable; contracts that unconditionally abort remove the caller’s ability to recover (e.g., from allocation failure).
Missing Pieces and Alternatives
- Some lament effort on contracts while C still lacks standardized slice/span types or built‑in bounds‑safe arrays.
- D’s long‑standing contracts and other features (CTFE, modules, safer arrays, no preprocessor) are cited as models C/C++ could have followed.
- Static analysis and contract checking across translation units are discussed, but feasibility in a mutable, global‑state C world is seen as challenging.