10

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?

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 1
    Afaik gcc just handles exceptions differently using eh personality function. Godbolt just strip it. This [discussion](http://llvm.1065342.n5.nabble.com/Re-cfe-dev-Code-generation-for-noexcept-functions-td68484.html) seems related. – Dan M. Apr 26 '18 at 17:30
  • This question may be more on-point if `-O3` is used, as `-Ofast` disregards standards compliance. – Drew Dormann Apr 26 '18 at 17:32
  • 1
    @DanM. That's true, and one can see that in Godbolt output, too, one only needs to turn on '.text'. However, it's unclear, how EH personality function can diagnose whether the current instance of `f()` was called from `b()`. After jump instruction is executed, there will be no evidence on the stack that it was from there. – ach Apr 26 '18 at 17:37
  • 2
    See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82081 – ach Apr 26 '18 at 17:49

1 Answers1

1

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:

  • if you want to call terminate on uncaught exception, that's already the case
  • if you want no-throw exception safety guarantee, that doesn't provide it.

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 ?

Michael Doubez
  • 5,937
  • 25
  • 39