Compiler assistance for C++ exception safety
Discusses GCC options for exception handling, clarifying their scope and limitations for porting codebases.
This discussion addresses challenges in enabling C++ exceptions on codebases previously compiled with -fno-exceptions. Participants clarify that options like throw() to noexcept conversion and pragmas targeting exception specifications primarily affect exception contracts, not the implicit insertion of exception handling code. The core problem remains understanding where and why exceptions are introduced, especially with optimizations like LTO, which may not eliminate all implied exception handlers.
- proposer
Explains that GCC options related to exception specifications (like throw() to noexcept) do not address the core issue of invisible exception handling code insertion, which complicates porting to exception-enabled codebases.
“To my knowledge those options relate to exception specifications rather than exceptions as a whole, the former just turns throw() into noexcept, which doesn't seem like it'll help much with C++17 and above code. The latter can be pretty helpful, but I think it only controls the case where exception specifications are violated, such as a noexcept method calling a method with no exception specifica…”
- other
Initiated the discussion by describing mysterious compiler/linker errors and unexpected exception handler insertions when `-fno-exceptions` is removed.
“C++ exceptions can be a problematic issue when trying to enable them on a codebase that used to be compiled with -fno-exceptions set. Mysterious compiler and linker errors that used to not be an issue will suddenly appear if you try to remove the flag, or worse, exceptions and exception handling can invisibly be inserted into the assembled code in places where you don't want them to be in. In my…”
Technical Tradeoffs
- Enabling C++ exceptions can significantly increase code size and complexity due to the runtime support required for exception handling.
- Compiler optimizations like LTO may not always eliminate all exception handling code, leading to potential bloat and performance overhead.
In Details
This thread discusses the complexities of enabling C++ exceptions in a large codebase that previously relied on -fno-exceptions. The issue revolves around the compiler (GCC) implicitly inserting exception handling code, even in code that does not explicitly use exceptions or standard library components that throw. Optimizations like Link-Time Optimization (LTO) do not appear to eliminate these handlers, leading to unexpected behavior and build failures. Participants are clarifying the scope of compiler flags related to exception specifications versus the fundamental generation of exception-…
- -fno-exceptions
- A GCC compiler flag that disables the generation of code for C++ exception handling, suppressing runtime support for
throw,try, andcatch. - noexcept
- A C++ specifier that indicates a function is not expected to throw exceptions. Compilers may optimize code more aggressively when
noexceptis used. - LTO
- Link-Time Optimization is a compiler optimization technique where the linker performs optimizations across multiple object files, potentially leading to better code than traditional link-time optimizations.
- Exception specifications
- In C++, constructs like
throw()that declare which exceptions a function might throw. These have been superseded bynoexceptin modern C++. - exception handler
- A block of code designed to catch and manage exceptions that are thrown during program execution.