<chrono>溢出保证

时间:2016-02-05 10:46:52

标签: c++ c++11 std integer-overflow chrono

我有这段代码:

auto time_point_a = std::chrono::high_resolution_clock::now();
while (true) {
  auto time_point_b = std::chrono::high_resolution_clock::now();
  auto counter_ms = std::chrono::duration_cast<std::chromo::milliseconds(time_point_b - time_point_a);
  // more code
std::cont << counter_ms.count() << std::endl;
}

counter_ms.count()保证始终返回有效值吗? count()有没有机会投掷?如果counter_ms超过其底层整数类型的大小会发生什么(我认为它是long long)?我的程序将连续运行几天,我需要知道当counter_ms变得太大时会发生什么。

1 个答案:

答案 0 :(得分:9)

  

counter_ms.count()是否保证始终返回有效值?

counter_ms保存单个有符号整数计数毫秒。 .count()成员函数被指定为什么都不做,只返回这个带符号的整数值。

  

count()是否有可能抛出?

此成员函数未标记为noexcept,原因有两个:

  1. noexcept在std :: lib中非常谨慎地使用。
  2. 通常,允许持续时间基于算术仿真器,算术仿真器可能具有投掷拷贝构造函数。
  3. counter_ms的情况下,表示必须是有符号的整数类型,当然不能用于复制构造。

    没有机会抛出。

      

    如果counter_ms超过其基础整数类型的大小会发生什么(我认为它很长)?

    您可以使用以下程序检查基础整数类型:

    #include <chrono>
    #include <iostream>
    #include "type_name.h"
    
    int
    main()
    {
        std::cout << type_name<std::chrono::milliseconds::rep>() << '\n';
    }
    

    其中描述了“type_name.h”here。对我来说,这个程序输出:

    long long
    

    标准规范说这种类型必须是至少45位的有符号整数类型。这使它的范围至少为+/- 557年。您可以使用以下程序找到milliseconds的实施范围:

    #include <chrono>
    #include <iostream>
    
    int
    main()
    {
        using days = std::chrono::duration
            <int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
        using years = std::chrono::duration
            <int, std::ratio_multiply<std::ratio<146097, 400>, days::period>>;
    
        std::cout << std::chrono::duration_cast<years>
            (std::chrono::milliseconds::min()).count() << " years\n";
        std::cout << std::chrono::duration_cast<years>
            (std::chrono::milliseconds::max()).count() << " years\n";
    }
    

    对我而言输出:

    -292277024 years
     292277024 years
    

    巧合的是,我实现了我正在使用的<chrono>实现(libc++)。实际范围远大于所需的最小范围的原因是我无法找到45位有符号整数类型,并且必须满足64位有符号整数类型。

    超出此范围时,您将获得与有符号整数算术溢出(指定为未定义行为)完全相同的行为。