我看到一个奇怪的问题,如果我定义了一个析构函数,那么成员方法就不会被内联。
示例代码:
#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类上工作)。
从成员方法返回原始类型似乎是正确内联的,当我返回我的类的实例时,这只是一个问题。
答案 0 :(得分:2)
Visual Studio将具有析构函数(空或非空)的类视为“复杂”,并且它们更可能放弃某些优化。如果您的类简单且速度敏感,请使用默认的析构函数。
答案 1 :(得分: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);
}