返回引用 gcc 时,0x30 添加到 %eax

When returning a reference gcc adds 0x30 to %eax

本文关键字:添加 %eax 0x30 引用 gcc 返回      更新时间:2023-10-16

我有一个函数并调用它:

Class1& Class2::get()
{
   return *m_ptr;
}
Class1& c = m_class2->get();

m_ptr 是一个自定义智能指针,我可以在调试器中看到 m_ptr.m_p 为 0,我也可以在其运算符 T* 中看到它确实返回 0。但是 c (&c) 的地址不是 NULL,它是0x30!我在拆解中看到的:

13059       return *m_ptr;
eaabbc7e:   mov 0x8(%ebp),%eax
eaabbc81:   add $0xb4,%eax
eaabbc86:   mov %eax,(%esp)
eaabbc89:   call 0xea9ce4c0  <operator T*>
eaabbc8e:   add $0x30,%eax
13060     }

就在行添加 $0x30,%eax 之前,我可以看到 %eax 为 0,即运算符正确返回 NULL。

为什么添加0x30的行在这里???

虽然没有足够的

信息来回答,但您的评论暗示Class2涉及多重继承,我会冒险猜测模板参数T派生类,而不是Class2本身。

因此operator T*返回指向此派生类的指针。为了取消引用它以给出Class2&,它必须转换为Class2*,这可能涉及向指针添加偏移量,这取决于编译器如何在对象中布置基类子对象。

显然,这仅在指针不为 null 时才有效;这就是为什么即使您只使用结果来初始化引用,也绝不能取消引用 null 指针的原因之一。

如果函数返回 Class2* ,那么您将按预期获得一个空指针;需要该转换才能将 null 转换为 null。在您的情况下,由于在这种情况下通过取消引用指针来调用未定义的行为,因此编译器无需在执行转换之前检查 null。