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_distributionbeing 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::regexand 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
noexceptdoes not statically forbid throwing; it instead guarantees that if an exception escapes,std::terminateis called. - That guarantee must be implemented, adding metadata and complexity; some compilers historically inhibited inlining across
noexceptboundaries.
Performance: where noexcept helps
- Clear wins:
std::vectoruses move instead of copy only if moves arenoexcept, affecting reallocation cost.std::unordered_*may avoid storing hashes if the hash functor isnoexcept, reducing memory.
- On “zero-cost” EH platforms, normal execution pays almost no runtime cost;
noexceptmainly 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
noexceptwas oversold as a free optimization; inlining with mixednoexcept/non-noexceptregions is especially tricky. - One proposed alternative (not adopted): make violations UB so compilers can treat
noexceptas 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
noexceptthat only calls othernoexceptcode, but others note practical issues with C libraries and existing ecosystems.
Exceptions, tooling, and methodology
- Some projects simply compile with
-fno-exceptionsto 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
noexceptvs non-noexcept. - Timing methodology (choice of clock, lack of clear harness) is questioned.
- Example code sometimes shows identical assembly for
- General advice: use tools like Compiler Explorer to inspect codegen rather than relying on folklore about exceptions and
noexcept.