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

为何std::unique_ptr的访问开销看似高于自定义结构体?

关于std::unique_ptr与自定义结构体汇编差异的疑问

测试代码

struct Ptr {
    int* x;
};

int* custom_struct(Ptr p) {
    return p.x;
}
int* unique_ptr(std::unique_ptr<int> x) {
    return x.get();
}

编译生成的汇编代码

custom_struct(Ptr):
        mov     rax, rdi
        ret
unique_ptr(std::unique_ptr<int, std::default_delete<int> >):
        mov     rax, QWORD PTR [rdi]
        ret

我原本以为std::unique_ptr的内存布局和我定义的Ptr结构体一致,想不通为什么访问std::unique_ptr时需要从内存加载(即[rdi]),而自定义结构体直接返回rdi即可——这才是我预期中unique_ptr该有的表现。


原因解释

核心差异来自函数参数的调用约定规则:

  • 自定义结构体Ptr是仅包含单个指针的平凡可复制类型,在x86-64的System V调用约定下,这类体积较小的平凡类型会直接通过寄存器(此处为rdi)传递。函数返回p.x本质就是返回整个结构体的内容(因为结构体本身等价于那个指针),所以汇编直接执行mov rax, rdi就能完成。
  • std::unique_ptr虽然逻辑上只持有一个指针,但它属于非平凡类型(自带自定义的移动构造、析构等特殊成员函数)。按照调用约定,非平凡类型的参数会被分配到栈上,函数收到的rdi是指向栈上该对象的指针。因此要获取其内部的指针值,必须通过[rdi]寻址到栈内存中读取。

如果把unique_ptr的参数改为传引用,就能看到和自定义结构体类似的汇编结果:

int* unique_ptr(std::unique_ptr<int>& x) {
    return x.get();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:03:11