2010-03-21 51 views
4

我有下面的代码额外的代码:GCC发出升压:: shared_ptr的非关联

#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编译。

+0

如果您通过值而不是通过引用传递'shared_ptr',会发生什么?或者相反,如果你通过引用传递'Foo *'会发生什么? – greyfade 2010-03-21 23:09:55

+0

@greyfade,奇怪的是,为函数发出的代码是完全一样的,但在调用网站的参考。计数由于复制而发生改变 – 2010-03-21 23:47:24

回答

7

这不是一个“冗余”指令。

第一代码段的相关部分等同于: * P

虽然在第二它等同于: ** P

由于shared_ptr的的内部有间接的第二级。这不是优化器可以“修复”的东西。

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

编辑:

哎呀!我的道歉,我误解你的代码。

您正在代码中传递参考中的shared_ptr。这将在ASM级别“通过指针”传递它。

所以你传递一个指向shared_ptr的指针,并且该shared_ptr包含一个指向你的对象的指针。

因此这两个层次的间接。

对不起,我感到困惑。 :)

+0

嗯,似乎boost的实现实际上包含了直接在它的主体中的对象的指针,所以第二级间接只用于递增/递减引用计数(访问共享ref.counter结构)。访问一个指针应该只是一个间接寻址。 – 2010-03-21 23:20:16

+0

你是对的,我误解了。 第二级间接寻址是由引用传递的shared_ptr引起的。 – RaptorFactor 2010-03-21 23:30:20

+0

好的,那里。 – 2010-03-21 23:38:44