C++'s `noexcept` can sometimes help or hurt performance

C++ developers weigh how the `noexcept` keyword actually affects performance and safety, noting that it can enable certain optimizations (e.g., for move operations or hash tables) but also add hidden overhead, especially when compilers must preserve the guarantee to call `std::terminate` if an exception escapes. Several comments argue that compilers already infer non-throwing behavior in many cases, and that the real costs come from metadata, inlining constraints, and exception machinery rather than the keyword itself. The conversation broadens into a critique of C++’s specification‑driven standard library and exception model, contrasting it with alternatives like Rust or third‑party C++ libraries, and highlighting trade‑offs between reproducibility, portability, and performance.

Deterministic randomness & standard-library portability

  • Several comments focus on std::uniform_int_distribution being implementation-defined across libraries, breaking deterministic tests and fuzzing.
  • Some see this as a major flaw: a “standard” library that behaves differently per platform is called “absurd” and “under/over-specified.”
  • Others defend the choice: different architectures (CPUs, GPUs) need different algorithms; over-specifying implementations (as with std::regex and standard hash tables) is blamed for bad performance.
  • Suggested workaround: use Boost or other libraries when reproducible randomness is required.

Spec vs single reference implementation

  • One camp argues the C++ committee should ship code (a single stdlib implementation) instead of a spec, citing Rust’s approach and faster evolution.
  • The opposing camp sees a spec as a long-term strength: cross-vendor experimentation, platform-specific optimizations, and lessons feeding back into the standard.
  • Disagreement on whether multiple “real” standard library implementations meaningfully exist; many cited alternatives (EASTL, HPX, Abseil, Folly, libcu++) are partial or non-std::-namespace.

What noexcept actually does

  • Clarified that noexcept does not statically forbid throwing; it instead guarantees that if an exception escapes, std::terminate is called.
  • That guarantee must be implemented, adding metadata and complexity; some compilers historically inhibited inlining across noexcept boundaries.

Performance: where noexcept helps

  • Clear wins:
    • std::vector uses move instead of copy only if moves are noexcept, affecting reallocation cost.
    • std::unordered_* may avoid storing hashes if the hash functor is noexcept, reducing memory.
  • On “zero-cost” EH platforms, normal execution pays almost no runtime cost; noexcept mainly affects code size and certain optimization choices.

Performance: where noexcept can hurt or confuse

  • Overusing noexcept (marking functions that can throw) forces compilers to maintain termination paths and unwinding metadata, potentially bloating binaries or affecting inlining.
  • Some backend engineers argue noexcept was oversold as a free optimization; inlining with mixed noexcept/non-noexcept regions is especially tricky.
  • One proposed alternative (not adopted): make violations UB so compilers can treat noexcept as a pure optimization hint.

Compiler analysis & checked-exception analogies

  • Compilers can infer that some functions don’t throw, but cannot in general decide this for all call graphs.
  • Some wished for Java-like checked exceptions or a stricter noexcept that only calls other noexcept code, but others note practical issues with C libraries and existing ecosystems.

Exceptions, tooling, and methodology

  • Some projects simply compile with -fno-exceptions to avoid overhead and complexity.
  • Notes on implementation:
    • Historical GCC unwinding used a global lock; newer work aims to scale better.
    • On some platforms, overhead is mostly in unwind tables, not instruction cost.
  • Several commenters criticize the article’s benchmarks:
    • Example code sometimes shows identical assembly for noexcept vs non-noexcept.
    • Timing methodology (choice of clock, lack of clear harness) is questioned.
  • General advice: use tools like Compiler Explorer to inspect codegen rather than relying on folklore about exceptions and noexcept.