<chrono>溢出保证

Mar*_*s K 5 c++ std integer-overflow c++11 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;
}
Run Code Online (Sandbox Code Playgroud)

counter_ms.count()保证始终返回一个有效的价值?有没有count()抛出的机会?如果counter_ms超过其底层整数类型的大小会发生什么(我估计它long long)?我的程序将连续运行几天,我需要知道如果/什么时候counter_msTOO很大会发生什么.

How*_*ant 10

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

counter_ms保持单个有符号整数的毫秒数.该.count()成员函数指定什么也不做,只是返回该整型值.

count()有没有机会抛出?

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

  1. noexcept 已经在std :: lib中非常谨慎地使用了.
  2. 通常,允许持续时间基于算术模拟器,算术模拟器可能具有抛出复制构造函数.

在这种情况下counter_ms,表示必须是有符号整数类型,当然不能抛弃复制结构.

没有机会抛出这个.

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

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

#include <chrono>
#include <iostream>
#include "type_name.h"

int
main()
{
    std::cout << type_name<std::chrono::milliseconds::rep>() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这里描述 "type_name.h" .对我来说,这个程序输出:

long long
Run Code Online (Sandbox Code Playgroud)

标准规范说这种类型必须是至少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";
}
Run Code Online (Sandbox Code Playgroud)

对我来说输出:

-292277024 years
 292277024 years
Run Code Online (Sandbox Code Playgroud)

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

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