请考虑以下代码段:
void f();
void a() { f(); }
void b() noexcept { f(); }
在上面的场景中,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()
但是,g++ -Ofast -std=c++2a
不是(主干版本):
a():
jmp f()
b():
jmp f()
g++
如何逃脱这一点?由于f
的正文不可见,因此无法在调用方生成代码吗?
......或者这只是一个奇怪的Compiler Explorer怪癖?
答案 0 :(得分:1)
正如@ach回答的那样,有一个bug opened on gcc bug tracker。但是,我可以这么说,这不是主要问题。
影响是异常将泄漏而不是终止程序,但是:
我能想到的唯一情况是在开发过程中。或者在环境中,如果合同被破坏(当生命受到威胁时),则必须失败;在这种情况下,编译器和要使用的功能受到严格控制。
安德烈(Andrzej)在his article - noexcept — what for ?做一个很好的案例