You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何引入析构函数会导致代码生成劣化?(寄存器传值变传引用)

空析构函数导致代码生成差异的问题

示例代码

struct has_destruct_t {
    int a;
    ~has_destruct_t()  {}
};

struct no_destruct_t {
    int a;
};


int bar_no_destruct(no_destruct_t);
int foo_no_destruct(void) {
    no_destruct_t tmp{};
    bar_no_destruct(tmp);
    return 0;
}

int bar_has_destruct(has_destruct_t);
int foo_has_destruct(void) {
    has_destruct_t tmp{};
    bar_has_destruct(tmp);
    return 0;
}

代码生成差异

foo_has_destruct的代码生成质量稍差,因为析构函数似乎迫使tmp存入栈中:

foo_no_destruct():                   # @foo_no_destruct()
        pushq   %rax
        xorl    %edi, %edi
        callq   bar_no_destruct(no_destruct_t)@PLT
        xorl    %eax, %eax
        popq    %rcx
        retq
foo_has_destruct():                  # @foo_has_destruct()
        pushq   %rax
        movl    $0, 4(%rsp)
        leaq    4(%rsp), %rdi
        callq   bar_has_destruct(has_destruct_t)@PLT
        xorl    %eax, %eax
        popq    %rcx
        retq

问题

既然该析构函数1)可平凡内联且2)为空,为何仍会出现这种情况?是否存在零成本添加析构函数的方法?

解答

手动声明空析构函数会让结构体失去平凡可析构的属性——C++标准规定,只有未声明析构函数,或者析构函数被显式默认(= default)的类型,才属于平凡可析构类型。平凡可析构类型的对象在生命周期结束时不需要执行任何析构操作,编译器因此拥有更大的优化空间,比如直接在寄存器中构造参数并传递,无需将对象存入栈中。

要实现零成本添加析构函数,只需将空析构函数替换为显式默认的版本:

struct has_destruct_t {
    int a;
    ~has_destruct_t() = default;
};

这样结构体依然保持平凡可析构特性,编译器会生成与foo_no_destruct一致的优化代码,既保留了析构函数的声明,又不会带来额外的性能开销。

内容的提问来源于stack exchange,提问作者Noah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:22:19