Skip to content
败犬日报 2026-02-28

败犬日报 2026-02-28

1. noexcept 标记自定义函数能优化性能吗

noexcept 优化性能的例子,基本上只有移动构造或赋值。一般来说移动构造与移动赋值有 noexcept 保证时,vector 等有强异常安全保证的 STL 容器会使用移动,否则使用拷贝。也就是说,不加 noexcept,很多情况下移动构造等于白写。

除此之外影响很小。在零成本异常模型(如 Itanium ABI)下,理论上可以做到完全不影响非异常路径的代码。没错就是连一行代码都不会多。

例如:

cpp
void foo();
void foo_noexcept() noexcept;

int bar() {
    try {
        foo();
    } catch (...) {
        return 1;
    }
    return 0;
}

int bar_noexcept() {
    try {
        foo_noexcept();
    } catch (...) {
        return 1;
    }
    return 0;
}

// bar():
//         sub     rsp, 8
//         call    foo()
//         xor     eax, eax
// .L1:
//         add     rsp, 8
//         ret
//         jmp     .L2

// bar() (.cold):
// .L2:
//         mov     rdi, rax
//         call    __cxa_begin_catch
//         call    __cxa_end_catch
//         mov     eax, 1
//         jmp     .L1

// bar_noexcept():
//         sub     rsp, 8
//         call    foo_noexcept()
//         xor     eax, eax
//         add     rsp, 8
//         ret

可以看到 bar 和 bar_noexcept 的汇编几乎一样,只是多了 bar() (.cold) 这个异常路径,对非异常路径是没有影响的。

注意我说了“理论上”,实际上会出现本来能做的优化,加了或去掉 noexcept 就不优化了的情况,可以属于编译器 bug。