C and C++ prioritize performance over correctness (2023)
Role and Purpose of Undefined Behavior (UB)
- Several comments dispute the article’s framing that C/C++ “prioritize performance over correctness.”
- One camp says UB primarily gives compilers latitude to optimize under the assumption “this never happens,” and that this does translate into performance gains.
- Another argues UB originated mainly as a compatibility device: to standardize C across diverse hardware and existing codebases without breaking them, not as an optimization trick.
- There’s also a view that C/C++ prioritize “programmer control” over both performance and correctness; the programmer defines what inputs are valid and promises to avoid UB.
“Reasonable” vs “Unreasonable” UB
- Many agree current UB space is too large and too surprising (e.g., signed overflow enabling arbitrary behavior).
- Some advocate narrowing UB to “undefined result” rather than “anything at all can happen,” or turning more cases into implementation-defined or unspecified behavior.
- Others insist UB must remain UB: the contract explicitly says “if you trigger this, all bets are off,” and compilers rely on that to transform code.
Signed Integer Overflow and Optimization
- A major thread focuses on signed overflow: textbooks use
for (int i=0; i<n; i++), but with 32‑bitintand 64‑bit pointers, defined overflow can force extra sign-extension and block loop optimizations. - One side sees this as a strong argument for overflow-as-UB to enable efficient induction-variable widening; another argues compilers could special-case common patterns or accept small slowdowns.
- Debate extends into “unspecified vs undefined” semantics and the internal “poison” model in modern IRs.
Diagnostics, Sanitizers, and Practical Tradeoffs
- Some say the problem isn’t UB itself but lack of good diagnostics; UB-based optimizations should remain, with better tools to surface potential UB.
- Others counter that any UB subtle enough to evade compile-time detection is also too subtle for humans, making this unrealistic.
- Sanitizers, trapping flags, and newer standards (e.g., defined uninitialized values) are cited as partial progress.
Comparisons to Other Languages and Ecosystem Choices
- Rust is highlighted as proof you can still have UB but restrict it to opt‑in “unsafe” blocks and a smaller rule set, enabling tooling like interpreters to catch violations.
- Newer languages with bounds checks and safer abstractions are said to impose modest (~tens of percent) overhead for much easier correctness.
- Some developers prefer living with UB to keep peak performance and low-level control; others argue the industry is increasingly willing to accept small regressions for safety.