返回参考时,gcc将0x30添加到%eax

时间:2012-04-19 09:53:23

标签: c++ linux pointers gcc disassembly

我有一个功能并调用它:

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的行在这里???

1 个答案:

答案 0 :(得分:4)

虽然没有足够的信息可以回答,但您的评论暗示Class2涉及多重继承,我会猜测模板参数T是派生类,而不是Class2本身

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

显然这只有在指针不为空时才有效;这就是为什么你必须永远不要取消引用空指针的一个原因,即使你只是使用结果初始化一个引用。

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