https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86286
Bug ID: 86286 Summary: Could __attribute__ ((nothrow)) on a noexcept function turn off EH codegen? Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- We generate ideal code for a noexcept function calling a noexcept function: int f (int i) noexcept; int foo (int i) noexcept { return f (i); } _Z3fooi: .LFB1: .cfi_startproc jmp _Z1fi .cfi_endproc .LFE0: But when a noexcept function calls a non-noexcept function there is additional code needed to call std::terminate if an exception occurs: _Z3gooi: .LFB1: .cfi_startproc .cfi_personality 0x3,__gxx_personality_v0 .cfi_lsda 0x3,.LLSDA1 jmp _Z1gi .cfi_endproc .LFE1: .globl __gxx_personality_v0 .section .gcc_except_table,"a",@progbits .LLSDA1: .byte 0xff .byte 0xff .byte 0x1 .uleb128 .LLSDACSE1-.LLSDACSB1 .LLSDACSB1: .LLSDACSE1: .text If we know that the non-noexcept function definitely won't throw (e.g. because we've explicitly checked its preconditions, or we just have additional knowledge about the state of the program) we can eliminate that extra code with a nothrow wrapper: inline int g2 (int i) __attribute__((always_inline,nothrow)); inline int g2 (int i) { return g(i); } int good (int i) noexcept { return g2 (i); } _Z4goodi: .LFB3: .cfi_startproc jmp _Z1gi .cfi_endproc .LFE3: But this is awkward and doesn't scale. It's possible wrap the call in a lambda using the attribute, but that's still awkward, and less readable: int good (int i) noexcept { return [&]() __attribute__((nothrow)) { return g (i); }(); } Would it be possible for the nothrow attribute to do that automatically when placed on a noexcept function? i.e. instead of the g2 wrapper we'd just do: int good (int i) noexcept __attribute__((nothrow)); int good (int i) noexcept { return g (i); } I'd like this to declare a function that never throws (which 'noexcept' guarantees), but also never needs to deal with exceptions coming from below it. There could be code today which uses both noexcept and __attribute__ ((nothrow)), maybe for pre-C++11 compatibility: #ifdef __GNUC__ # define NOTHROW __attribute__((nothrow)) #endif #if __cplusplus >= 201103L # define NOEXCEPT noexcept #else # define NOEXCEPT #endif void f() NOEXCEPT NOTHROW; If we're concerned about changing the behaviour of this code (from guaranteed termination in C++11 and later if the function exits via an exception, to UB) then maybe a new attribute would be better.