I just read a post on frame pointer omission (FPO) optimization, also known as /Oy compiler flag. And a comment from Vladimir Scherbina on problems getting the feature actually work. I wondered if there has been any improvement with a Visual Studio .NET 2008 SP1. latest compiler from Microsoft and briefly – the result is yes, the feature seems to be working.
This is the reference code for the feature:
const volatile INT g_nValueA = 0; const volatile INT g_nValueB = 0; #pragma optimize("y", off) __declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE A(const volatile INT& nValue = g_nValueA) { return nValue != 0; } #pragma optimize("y", on) __declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE B(const volatile INT& nValue = g_nValueB) { return nValue != 0; } int _tmain(int argc, _TCHAR* argv[]) { A(); B(); return 0; }
The code is to be compiled in Release and function A is to be not optimized while B is subject for optimization and omitting the frame pointer.
Disassembly shows for A:
__declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE A(const volatile INT& nValue = g_nValueA) { 00401000 push ebp 00401001 mov ebp,esp return nValue != 0; 00401003 mov eax,dword ptr [nValue] 00401006 mov ecx,dword ptr [eax] 00401008 xor eax,eax 0040100A test ecx,ecx 0040100C setne al } 0040100F pop ebp 00401010 ret 4
and for B:
__declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE B(const volatile INT& nValue = g_nValueB) { return nValue != 0; 00401020 mov eax,dword ptr [esp+4] 00401024 mov ecx,dword ptr [eax] 00401026 xor eax,eax 00401028 test ecx,ecx 0040102A setne al } 0040102D ret 4
and the difference is what was actually expected. It looked as it finally got to work but a check with Visual Studio versions 2003 and 2005 shown that optiomization makes a difference on older versions too.