When disassembling my application, I have noticed that MSVC generates more assembly opcodes when I'm calling a static method compared to an instance method. This is true even when both functions are identical (so the instance method is not using this).
Code example:
struct matrix4
{
float m[16];
static const matrix4 identity;
static matrix4 translation1(float x);
matrix4 translation2(float x) const;
};
func(matrix4::translation1(0));
func(matrix4::identity.translation2(0));
The generated code will look like this:
call static matrix4 matrix4::translation1(float) ; matrix4::translation1
push 16 ; 00000010H
mov esi, eax
lea edi, DWORD PTR $T2[ebp]
pop ecx
lea eax, DWORD PTR $T2[ebp]
rep movsd
push eax
call void func(matrix4 const &) ; func
[...]
mov ecx, OFFSET static matrix4 const matrix4::identity ; matrix4::identity
call matrix4 matrix4::translation2(float)const ; matrix4::translation2
push eax
call void func(matrix4 const &) ; func
For my application, I care about the generated file size. It looks like I should replace all my static methods with instance methods, which seems really surprising to me. I'd rather avoid that because it means changing a lot of code. Did I miss anything?
Repro: https://godbolt.org/z/o3x5vKGdK (compare block1 and block2)
I have noticed similar issues with other compiler flags (with and without /Os). The same happens whether the method is inlined or not.
Clang doesn't seem to have this behavior. If that's a MSVC optimization bug, is there a simple workaround?
(I noticed the problem when I upgraded my code from Visual Studio 2010 to more recent VS versions. VS2010 was generating a smaller executable.)