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

为何MSVC成员函数从不通过RAX寄存器返回结构体?

Windows x64 ABI中自由函数与成员函数返回结构体的差异及设计原因

我在MSVC代码生成过程中发现一个现象:满足x64 API中通过RAX寄存器返回条件的结构体,在自由函数和成员函数中的处理逻辑存在明显差异。

示例代码如下:

struct Result
{
    uint64_t value;
};

Result makeResult(uint64_t value)
{
    return { value };
}

struct ResultFactory
{
    NOINLINE Result MakeResult(uint64_t value) const
    {
        return { value };
    }
};

上述Result结构体完全符合x64 API中通过RAX寄存器返回的要求,自由函数的汇编代码也确实遵循了这一逻辑:

value$ = 8
Result makeResult(unsigned __int64) PROC ; makeResult, COMDAT
  mov rax, rcx
  ret 0
Result makeResult(unsigned __int64) ENDP ; makeResult

但成员函数的汇编代码却采用了不同的处理方式:

Result ResultFactory::MakeResult(unsigned __int64)const  PROC ; ResultFactory::MakeResult, COMDAT
  mov QWORD PTR [rdx], r8
  mov rax, rdx
  ret 0
Result ResultFactory::MakeResult(unsigned __int64)const  ENDP ; ResultFactory::MakeResult

编译器要求成员函数通过RDX寄存器传递Result的引用(MSVC成员函数中当无法用RAX返回时会使用第二个寄存器)。这种设计会无端降低代码生成效率,导致非内联场景下成员函数与自由函数出现性能差异,甚至有时返回原生类型再通过bit_cast转换反而更快。而Clang/GCC的处理逻辑则符合预期——直接用RAX返回该结构体。

最初我不确定这是MSVC的特性还是x64 Windows调用约定的要求(MSDN并未明确说明相关C++细节),后来经@Turtlefight指出这是Windows ABI的规定。现在我的疑问是:Windows ABI为何要做出这种区分?这似乎只会降低代码生成效率,还增加了全局函数与成员函数处理的复杂度,想了解背后的设计原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:42:33