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 2010(v100)も試しましたが、Visual Studio 2012(v110)を使用してリリースビルドとしてコンパイルされました。/ Ob2を設定して、運が悪かったのでメソッドをインライン化するように説得してみました。

私はアセンブリに精通していないので、アセンブリが何をしようとしているのかを正確に知ることはできません。おそらく明日、それを理解して、ヒントが得られるかどうかを確認しようと思います。空のデストラクタを定義するとメソッドがインライン化されなくなる理由を誰かが明らかにすることはできますか?

編集[2012年11月17日]

上記のコードをはるかに単純になるように更新しました(元々は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 に答える