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

为何C风格结构体模拟类会产生额外汇编指令?

问题

为了模拟C类的开销,我用带“成员”函数指针的C风格结构体与C类做对比,原本以为二者指令数大致相当,结果发现C实现调用“成员”函数时会多一条额外指令。以下是测试代码及对应汇编指令(编译器:ARM GCC 12.2.0(linux)):

测试代码(main函数)

int main()
{
    uint32_t a;
    rectangle_t r;
    
    /* struct */
    r.set(2,3, &r);
    /* asm 
       ldr     r3, [r7, #12]
       adds    r2, r7, #4
       movs    r1, #3
       movs    r0, #2
       blx     r3
    */

    a = r.getArea(&r);
    /* asm 
       ldr     r3, [r7, #16]
       adds    r2, r7, #4
       mov     r0, r2
       blx     r3
       str     r0, [r7, #20]
       movs    r3, #0
    */

    /* Class */
    r.set(2, 3);
    /* asm 
       adds    r3, r7, #4
       movs    r2, #3
       movs    r1, #2
       mov     r0, r3
       bl      rectangle_t::set(unsigned int, unsigned int)
    */
    a = r.getArea();
    /* asm 
       adds    r3, r7, #4
       mov     r0, r3
       bl      rectangle_t::getArea()
       str     r0, [r7, #12]
       movs    r3, #0
    */
}

声明代码

typedef struct rectangle rectangle_t;
struct rectangle
{
    uint32_t w;
    uint32_t l;
    void (*set)(uint32_t L, uint32_t W, rectangle_t *self);
    uint32_t (*getArea)(rectangle_t *self);    
};
void set(uint32_t L, uint32_t W, rectangle_t *self)
{
    self->w = W;
    self->l = L;
}

uint32_t getArea(rectangle_t *self)
{
    return self->l * self->w;
}

class rectangle_t
{
public:    

    uint32_t w;
    uint32_t l;   
    void set(uint32_t L, uint32_t W);
    uint32_t getArea(); 
};

void rectangle_t::set(uint32_t L, uint32_t W)
{
    w = W;
    l = L;
}

uint32_t rectangle_t::getArea()
{
    return l * w;
}

请问:为何调用结构体“成员”函数比C++类成员函数多一条ldr指令?


回答

核心原因是两者的函数地址绑定机制完全不同:

  • C++非虚成员函数是静态绑定:编译阶段就已经确定了rectangle_t::set、rectangle_t::getArea的绝对地址,调用时直接通过bl指令跳转到固定地址,不需要额外的内存读取操作。

  • C结构体的函数指针是动态存储:你的C实现把函数指针存在结构体实例的内存中,调用时必须先从结构体的对应偏移位置(比如[r7, #12])读取指针值到寄存器(也就是那条额外的ldr指令),再通过blx r3跳转执行。这一步内存读取是C实现无法避免的——因为函数指针的具体位置只有运行时才能确定。

如果想让C实现的指令数接近C++,可以直接硬编码调用函数(比如直接写set(2,3,&r)),但这样就失去了模拟类多态性的能力。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:35:36