c++ - <chrono> 溢出保证

标签 c++ c++11 std integer-overflow c++-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 变得太大时会发生什么。

最佳答案

Is counter_ms.count() guaranteed to always return a valid value?

counter_ms持有一个带符号的整数毫秒数。 .count()指定成员函数只返回这个有符号整数值。

Is there any chance that count() throws?

这个成员函数没有标记noexcept有两个原因:

  1. noexcept在 std::lib 中很少使用。
  2. 通常,持续时间允许基于算术模拟器,它可能具有抛出复制构造函数。

counter_ms的情况下,表示必须是带符号的整数类型,当然不能抛出复制构造。

这不可能抛出。

What happens if counter_ms exceeds the size of its underlying integral type (I reckon it's long long)?

您可以使用此程序检查底层整数类型:

#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 位有符号整数类型。

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

关于c++ - <chrono> 溢出保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35222170/

相关文章:

python - OpenCV VideoCapture 表示视频有 0 帧(C++ 和 Python)

c++ - 如何在不指定维度的情况下用 Eigen 声明张量?

c++ - 将工作项添加到数组或列表的非阻塞方式

c++ - 使用自定义比较器在 C++ 中声明 priority_queue

c++ - 在 C++ 中重载 operator new 和 operator new[] 有什么区别?

c++ - 从文件读取时出现段错误

c++ - 通过可变参数模板传递右值引用时出现编译器错误

c++ - 函数的引用限定符有什么实际用例吗?

c++ - std::wstring 长度

c++ - 派生 std::ofstream 并重载 operator<<