C ++ Chrono 32/64位+发布/调试

时间:2018-01-05 11:11:38

标签: c++ x86-64 chrono

我在c ++ visual studio 2015中遇到了麻烦

考虑这个版本:

#ifndef CHRONO_INFO_H
#define CHRONO_INFO_H

#include <iostream>
#include <sstream>
#include <iomanip>
#include <chrono>

class c_ChronoInfo
{
private:
    std::chrono::steady_clock::time_point _start;
    std::chrono::steady_clock::time_point _stop;
    std::chrono::steady_clock::duration _totaltime;
    std::chrono::steady_clock::duration _laptime;
    bool _isPaused;

    const std::chrono::steady_clock::duration _zeroDuration = std::chrono::steady_clock::duration::zero();

public:
    c_ChronoInfo() :
        _totaltime(_zeroDuration),
        _isPaused(true)
    {
    }

    ~c_ChronoInfo() {}

    void Start()
    {
        assert(_isPaused);
        _isPaused = false;
        _start = std::chrono::steady_clock::now();
    }

    void Stop()
    {
        assert(!_isPaused);
        _stop = std::chrono::steady_clock::now();
        _laptime = _stop - _start;
        _totaltime += _laptime;
        _isPaused = true;
    }

private:
    inline auto _totalChronosI() const
    {
        return _totaltime;
    }

public:
    inline double TotalMilliseconds() const { return std::chrono::duration_cast<std::chrono::duration<double, std::chrono::milliseconds::period>>(_totalChronosI()).count(); }

};

#endif // CHRONO_INFO_H

当我在64位和释放模式下编译时,按照预期输出非常短的时间说:

c_ChronoInfo test;
test.Start();
int x = 0;
for (long long i = 0; i <= 100; ++i)
{
    x = i;
}
test.Stop();
std::cout << "test: " << test.TotalMilliseconds() << std::endl;

但是当我编译32位或调试(32或64)时,我得到负面或非常大的时间。

此外,_laptime变量在类中定义,但实际上并不需要。但是,如果在方法中根据需要定义,即

std::chrono::steady_clock::duration _laptime = _stop - _start;

即使在64位/释放模式下,代码也会完全出乎意料。

由于

2 个答案:

答案 0 :(得分:2)

您的类具有字段初始化重新排序问题_zeroDuration始终在_totaltime之后初始化,因为它们按此顺序声明,因此在调用_totaltime(_zeroDuration) _totaltime之后仍然充满了垃圾。要修复它,只需扔掉_zeroDuration

c_ChronoInfo() :
    _totaltime(std::chrono::steady_clock::duration::zero())

答案 1 :(得分:2)

非静态和非constexpr中的

_zeroDuration并且在您使用它来初始化构造函数初始化列表中的_totaltime时尚未初始化,因为它在类的后面声明了

所以碰巧内存中包含的值后来看起来像一个大的负浮点数。

要修复初始化顺序,您可以在_zeroDuration

之前移动_totaltime的声明
// first
const std::chrono::steady_clock::duration _zeroDuration = std::chrono::steady_clock::duration::zero();
...
// second
std::chrono::steady_clock::duration _laptime;
bool _isPaused;
...
c_ChronoInfo() :
    _totaltime(_zeroDuration),
    _isPaused(true)

或直接初始化_totaltime,如:

c_ChronoInfo() :
    _totaltime(std::chrono::steady_clock::duration::zero()),

或使_zeroDuration成为constexpr

static constexpr std::chrono::steady_clock::duration _zeroDuration = std::chrono::steady_clock::duration::zero();

您还可以更好地初始化&#39; std :: chrono :: duration&#39;的所有变量。键入因为它们默认的constexpr构造函数并且不是零初始化。

duration_cast中您不需要TotalMilliseconds

inline double TotalMilliseconds() const {
    return std::chrono::duration<double, std::milli>(_totalChronosI()).count();
}