8

我看到一个奇怪的问题,如果我定义析构函数,成员方法不会被内联。

示例代码:

#include <cstdio>

class Foo
{
public:
    Foo(int arg) : data(arg) {}
    ~Foo(void) {}

    Foo bar(void) const { return Foo(7); }

    int data;
};

int main(void)
{
        Foo a(3);
        Foo b = a.bar();

        printf ("%i", b.data);
}

如果使用默认析构函数,我会得到如下信息:

main:
 sub         rsp,28h  
 lea         rcx,[string "%i" (013FB8ADA0h)]  
 mov         edx,7  
 call        printf (013FB81068h)  
 xor         eax,eax  
 add         rsp,28h  
 ret  

但是如果我定义自己的空白析构函数,如上面的代码:

Foo::bar:
 mov         dword ptr [rdx],7  
 mov         rax,rdx  
 ret  

main:
 sub         rsp,28h  
 lea         rdx,[b]  
 call        Foo::bar (013FA11000h)  
 mov         edx,dword ptr [b]  
 lea         rcx,[string "%i" (013FA1ADA0h)]  
 call        printf (013FA11088h)  
 xor         eax,eax  
 add         rsp,28h  
 ret  

使用 Visual Studio 2012 (v110) 编译为发布版本,但也尝试了 Visual Studio 2010 (v100)。我尝试设置 /Ob2 以帮助说服它内联该方法,但没有运气。

我对汇编不够熟悉,无法确切知道它在做什么,也许明天我会试着弄清楚它是否给出任何提示。谁能解释为什么定义一个空的析构函数会阻止该方法被内联?

编辑 [17/11/2012]

我将上面的代码更新为更简单(最初我正在研究我的 Vector 类)。

从成员方法返回原始类型似乎正确内联,这只是当我返回我的类的实例时的问题。

4

2 回答 2

2

Visual Studio 将带有析构函数(无论是否为空)的类视为“复杂”类,它们更有可能放弃某些优化。如果您的类简单且对速度敏感,请使用默认析构函数。

于 2012-11-18T23:58:52.517 回答
0

在 VS 2010 中,编译器似乎在编译时计算最终值,并将其加载到堆栈中以获取a.
如下修改代码确实启用了定义析构函数的优化:

inline void operator = (const __m128 v)
{
    data = v;
}

inline __m128 operator* (const Vector4& a) const
{ 
    return _mm_mul_ps(data, a.data); 
}
于 2012-11-14T03:25:47.117 回答