This code example will output time: 0
regardless of the value of N
when compiled with Visual Studio Professional 2013 Update 3 in release mode, bot
If you look at the disassembly winddow using the debugger you can see the generated code. For VS2012 express in release mode you get this:
00AF1310 push edi
auto t0 = clock();
00AF1311 call dword ptr ds:[0AF30E0h]
00AF1317 mov edi,eax
auto r = g();
auto t1 = clock();
00AF1319 call dword ptr ds:[0AF30E0h]
cout << r << " time: " << t1-t0 << endl;
00AF131F push dword ptr ds:[0AF3040h]
00AF1325 sub eax,edi
00AF1327 push eax
00AF1328 call g (0AF1270h)
00AF132D mov ecx,dword ptr ds:[0AF3058h]
00AF1333 push eax
00AF1334 call dword ptr ds:[0AF3030h]
00AF133A mov ecx,eax
00AF133C call std::operator<<<std::char_traits<char> > (0AF17F0h)
00AF1341 mov ecx,eax
00AF1343 call dword ptr ds:[0AF302Ch]
00AF1349 mov ecx,eax
00AF134B call dword ptr ds:[0AF3034h]
from the first 4 lines of assembly you can see that the two calls to clock
(ds:[0AF30E0h]
) happen before the call to g
. So in this case it doesn't matter how long g
takes, the result will only show the time take between those two sequential calls.
It seems VS has determined that g
doesn't have any side effects that would affect clock
so it is safe to move the calls around.
As Michael Petch points out in the comments, adding volatile
to to the declaration of r
will stop the compiler from moving the call.