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

C++ Chrono 32/64 bits + Release/Debug

本文关键字:发布 调试 Chrono C++      更新时间:2023-10-16

我在使用 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 位/发布模式下,代码的行为也完全出乎意料。

谢谢

非静态和非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();

您最好初始化所有 'std::chrono::d uration' 类型的变量,因为它们具有默认的 constexpr 构造函数并且未初始化为零。


您不需要duration_cast TotalMilliseconds

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

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

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