返回引用 gcc 时,0x30 添加到 %eax
When returning a reference gcc adds 0x30 to %eax
我有一个函数并调用它:
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。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 将图像添加到资源文件夹UWP C++
- 返回引用 gcc 时,0x30 添加到 %eax