Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining a destructor prevents member functions being inlined

Tags:

c++

inline

I am seeing a strange issue where by member methods aren't getting inlined if I define a destructor.

Example code:

#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);
}

If using the default destructor, I get something like this:

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

But if I define my own blank destructor, as in the code above:

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  

Compiled as a release build using Visual Studio 2012 (v110), though also tried Visual Studio 2010 (v100). I tried setting /Ob2 to help persuade it to inline the method with no luck.

I'm not familiar enough with assembly to know exactly what it's trying to do, maybe tomorrow I'll try to figure that out to see it if gives any hints. Can anyone shed any light on why defining an empty destructor would prevent the method being inlined?

EDIT [17/11/2012]

I updated the code above to be much simpler (originally I was working on my Vector class).

Returning a primitive type from a member method seems to get inlined correctly, it's only an issue when I return an instance of my class.

like image 226
Gareth Avatar asked Nov 14 '12 02:11

Gareth


1 Answers

Visual Studio treats classes with destructors (empty or not) as "complex" and they will be more likely to abandon certain optimizations. If your class is simple and speed sensitive, use the default destructor.

like image 53
Fabien Avatar answered Nov 06 '22 06:11

Fabien