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‑bit int and 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.