<chrono> 溢出保证
<chrono> overflow guarantees
我有这段代码:
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()
是否保证始终 return 是一个有效值? count()
有可能抛出吗?如果 counter_ms 超过其基础整数类型的大小(我认为是 long long
),会发生什么情况?我的程序将连续几天 运行,我需要知道会发生什么 if/when counter_ms
变得太大了。
Is counter_ms.count() guaranteed to always return a valid value?
counter_ms
保存一个带符号的毫秒整数计数。 .count()
成员函数被指定除了 return 这个带符号的整数值之外什么都不做。
Is there any chance that count() throws?
这个成员函数没有标记noexcept
有两个原因:
noexcept
在 std::lib 中很少使用。
- 一般来说,持续时间允许基于算术模拟器,它可能有一个抛出复制构造函数。
在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 位有符号整数类型。
超出此范围时,您将得到与有符号整数算术溢出(指定为未定义行为)完全相同的行为。
我有这段代码:
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()
是否保证始终 return 是一个有效值? count()
有可能抛出吗?如果 counter_ms 超过其基础整数类型的大小(我认为是 long long
),会发生什么情况?我的程序将连续几天 运行,我需要知道会发生什么 if/when counter_ms
变得太大了。
Is counter_ms.count() guaranteed to always return a valid value?
counter_ms
保存一个带符号的毫秒整数计数。 .count()
成员函数被指定除了 return 这个带符号的整数值之外什么都不做。
Is there any chance that count() throws?
这个成员函数没有标记noexcept
有两个原因:
noexcept
在 std::lib 中很少使用。- 一般来说,持续时间允许基于算术模拟器,它可能有一个抛出复制构造函数。
在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 位有符号整数类型。
超出此范围时,您将得到与有符号整数算术溢出(指定为未定义行为)完全相同的行为。