c++ - 在接口(interface)不是时标记派生实现 noexcept 的副作用是什么

标签 c++ inheritance polymorphism noexcept

我们有一个实现 IUnknown(或我们不拥有的任何接口(interface))的类。我们开始用 noexcept 标记我们的大部分/所有方法以进行任何潜在的优化,因为我们无论如何都不会抛出任何异常;尽管我们依赖的一些库可能。提出了 QueryInterface/AddRef/Release 是否应该标记为 noexcept 的问题,因为接口(interface)不是。

当只有一些派生类被标记为 noexcept 时,是否有任何副作用或问题?

最佳答案

一般来说,您应该小心使用 noexcept。除非编译器可以证明该函数确实不会抛出任何异常,否则它必须插入一个动态处理程序以在出现异常时终止您的程序。因此,它不一定会导致您希望的优化。无论如何,将其添加到 AddRefReleaseQueryInterface 应该是安全的。

编辑

例如,考虑以下代码:

extern int Foo();

int Bar() noexcept
{
    return Foo();
}

这是 Clang 7.0 在 O3 上生成的内容:

Bar():                                # @Bar()
    push    rax
    call    Foo()
    pop     rcx
    ret
    mov     rdi, rax
    call    __clang_call_terminate
__clang_call_terminate:                 # @__clang_call_terminate
    push    rax
    call    __cxa_begin_catch
    call    std::terminate()

如果你删除 noexcept,你会得到这个:

Bar():                                # @Bar()
    jmp     Foo()                 # TAILCALL

在此示例中,主要效果只是使图像膨胀一点,但请注意对 Foo 的调用也变得有点低效。

关于c++ - 在接口(interface)不是时标记派生实现 noexcept 的副作用是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52938302/

相关文章:

c++ - 在 C++ 中提示可编辑的默认值?

c++ - VS2010 中 C++ lambda 表达式的奇怪错误(变量 y1)

C++:在非虚函数中使用纯虚函数

C++如何创建多态容器?

Java 状态模式具有不同的实现,导致难以理解的错误

c++ - 如何使用opencv提高测量精度

c++ - 将更多数据传递给 std :set Comparison class

java - 有没有办法将 "override"本质上作为最终变量?

javascript - 为什么 Javascript 默认不支持继承?

angularjs - Angular 动态多态指令