GCC 为 boost::shared_ptr 取消引用发出额外的代码

Posted

技术标签:

【中文标题】GCC 为 boost::shared_ptr 取消引用发出额外的代码【英文标题】:GCC emits extra code for boost::shared_ptr dereference 【发布时间】:2010-03-21 23:01:45 【问题描述】:

我有以下代码:

#include <boost/shared_ptr.hpp>

struct Foo  int a; ;
static int A;

void
func_shared(const boost::shared_ptr<Foo> &foo) 
    A = foo->a;


void
func_raw(Foo * const foo) 
    A = foo->a;

我认为编译器会创建相同的代码,但是对于shared_ptr 版本,会发出一条看似多余的指令。

Disassembly of section .text:

00000000 <func_raw(Foo*)>:
   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
   3:   8b 45 08                mov    eax,DWORD PTR [ebp+8]
   6:   5d                      pop    ebp
   7:   8b 00                   mov    eax,DWORD PTR [eax]
   9:   a3 00 00 00 00          mov    ds:0x0,eax
   e:   c3                      ret
   f:   90                      nop

00000010 <func_shared(boost::shared_ptr<Foo> const&)>:
  10:   55                      push   ebp
  11:   89 e5                   mov    ebp,esp
  13:   8b 45 08                mov    eax,DWORD PTR [ebp+8]
  16:   5d                      pop    ebp
  17:   8b 00                   mov    eax,DWORD PTR [eax]
  19:   8b 00                   mov    eax,DWORD PTR [eax]
  1b:   a3 00 00 00 00          mov    ds:0x0,eax
  20:   c3                      ret

我只是好奇,这是必要的,还是只是优化器的缺点?

g++ 4.1.2-O3 -NDEBUG编译。

【问题讨论】:

如果您通过值而不是通过引用传递shared_ptr 会发生什么?或者相反,如果您通过引用传递Foo* 会发生什么? @greyfade,奇怪的是,为该函数发出的代码完全相同,但在调用站点上是 ref。按值传递时由于复制而改变计数 【参考方案1】:

这不是“冗余”指令。

第一段代码sn -p的相关部分等价于: *p

虽然在第二个中它相当于: **p

由于 shared_ptr 的内部结构,存在第二级间接。这不是优化器可以“修复”的。

无论如何,差异可以忽略不计。

编辑:

哎呀!抱歉,我误读了您的代码。

您在代码中传递了 shared_ptr BY REFERENCE。这将在 ASM 级别“通过指针”传递它。

所以你传递了一个指向 shared_ptr 的指针,而 shared_ptr 包含一个指向你的对象的指针。

因此有两个间接级别。

很抱歉给您带来了困惑。 :)

【讨论】:

嗯,似乎 boost 的实现实际上直接在其主体中包含了对象的指针,所以第二级间接仅在增加/减少引用计数时使用(访问共享 ref.counter 结构)。访问指针应该只是一个间接的。 你说得对,我看错了。第二级间接是由 shared_ptr 通过引用引起的。 是的,确实如此!

以上是关于GCC 为 boost::shared_ptr 取消引用发出额外的代码的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 boost::shared_ptr 构造二叉树

boost---shared_ptr笔记

返回 boost::shared_ptr 和从返回的原始指针构造 boost::shared_ptr 有啥区别?

boost库之内存管理shared_ptr

Boost智能指针——shared_ptr

类的 boost::shared_ptr 作为结构成员