Consider the following code snippet:
void f();
void a() { f(); }
void b() noexcept { f(); }
In the scenario above, the body of f
is not visible to the compiler in the current translation unit. Therefore, since b
is marked noexcept
, additional code must be generated on the caller side to make sure that the exception is caught and std::terminate
is invoked.
That's what clang++ -Ofast -std=c++2a
does (trunk version):
a(): # @a()
jmp f() # TAILCALL
b(): # @b()
push rax
call f()
pop rax
ret
mov rdi, rax
call __clang_call_terminate
__clang_call_terminate: # @__clang_call_terminate
push rax
call __cxa_begin_catch
call std::terminate()
However, g++ -Ofast -std=c++2a
does not (trunk version):
a():
jmp f()
b():
jmp f()
live example on godbolt.org
How does g++
get away with this? Shouldn't code be generated on the caller side as the body of f
is not visible?
...or is this just a weird Compiler Explorer quirk?
As @ach answered, there is a bug opened on gcc bug tracker. But if I may say so, it is not a major issue.
The impact is that an exception will leak instead of terminating the program but:
The only case I can think of is during development. Or in environments were it is mandatory to fail if a contract is broken (when life is at stake) ; in this case, compilers and the feature to use are tightly controlled.
Andrzej is making a good case in his article - noexcept — what for ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With