您可以使用ctime重现或解释此Visual C ++错误吗? [英] Can you reproduce or explain this Visual C++ bug with ctime?
问题描述
此代码示例将输出 time:0
,而不管 N
的值如何>在发布模式下使用Visual Studio Professional 2013 Update 3进行编译时,可同时使用32位和64位选项:
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, both 32 and 64-bit option:
#include <iostream>
#include <functional>
#include <ctime>
using namespace std;
void bar(int i, int& x, int& y) {x = i%13; y = i%23;}
int g(int N = 1E9) {
int x, y;
int r = 0;
for (int i = 1; i <= N; ++i) {
bar(i, x, y);
r += x+y;
}
return r;
}
int main()
{
auto t0 = clock();
auto r = g();
auto t1 = clock();
cout << r << " time: " << t1-t0 << endl;
return 0;
}
在rextester.com上使用gcc,clang和其他版本的vc ++进行测试时,它的行为正确,并输出大于零的 time
.任何线索,这是怎么回事?
When tested with gcc, clang and other version of vc++ on rextester.com, it behaves correctly and outputs time
greater than zero. Any clues what is going on here?
我注意到,内联 g()
函数可以恢复正确的行为,但是更改 t0
, r
和 t1
不会.
I noticed that inlining the g()
function restores correct behaviour, but changing declaration and initialization order of t0
, r
and t1
does not.
推荐答案
如果使用调试器查看反汇编窗口,则可以看到生成的代码.对于处于发布模式的VS2012 Express,您会得到以下信息:
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]
在汇编的前4行中,您可以看到对 clock
的两次调用( ds:[0AF30E0h]
)发生在对 g <的调用之前./code>.因此,在这种情况下,
g
花费多长时间都没有关系,结果将仅显示两次连续调用之间的时间.
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.
似乎VS已确定 g
没有任何会影响 clock
的副作用,因此可以安全地移动呼叫.
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.
正如Michael Petch在注释中指出的那样,在 r
的声明中添加 volatile
将阻止编译器移动调用.
As Michael Petch points out in the comments, adding volatile
to to the declaration of r
will stop the compiler from moving the call.
这篇关于您可以使用ctime重现或解释此Visual C ++错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!