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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With