`nodcept`函数中的`std :: terminate`调用,可见性有限 - gcc vs clang codegen

Vit*_*meo 10 c++ code-generation exception noexcept c++11

请考虑以下代码段:

void f();

void a()          { f(); }
void b() noexcept { f(); }
Run Code Online (Sandbox Code Playgroud)

在上面的场景f中,当前转换单元中的编译器看不到正文.因此,由于b已标记noexcept,因此必须在调用方生成其他代码,以确保捕获并std::terminate调用异常.

这就是clang++ -Ofast -std=c++2a(主干版本):

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()
Run Code Online (Sandbox Code Playgroud)

但是,g++ -Ofast -std=c++2a(主干版):

a():
  jmp f()
b():
  jmp f()
Run Code Online (Sandbox Code Playgroud)

godbolt.org上的实例


怎么g++逃避这个?不应该在调用方生成代码,因为主体f不可见?

...或者这只是一个奇怪的Compiler Explorer怪癖?

Mic*_*bez 1

正如 @ach 回答的那样,gcc bug tracker 上打开了一个错误。但如果我可以这么说的话,这并不是一个大问题。

\n\n

其影响是异常会泄漏而不是终止程序,但是:

\n\n
    \n
  • 如果你想在未捕获的异常上调用终止,情况已经如此
  • \n
  • 如果您想要不抛出异常的安全保证,那么它并没有提供。
  • \n
\n\n

我能想到的唯一情况是在开发过程中。或者在如果违反合同就必须失败的环境中(当生命受到威胁时);在这种情况下,编译器和要使用的功能受到严格控制。

\n\n

Andrzej 在他的文章中提出了一个很好的案例- no except \xe2\x80\x94 有何用处?

\n