我的示例代码:
time_t time_tee = 253402210800;
auto tp = std::chrono::system_clock::from_time_t(time_tee);
time_t tee2 = std::chrono::system_clock::to_time_t(tp);
std::cout << tee2 << std::endl;
期望:输出2534022108输出:-4852206231
time_t为64位,因此不应有溢出。
我在这里触发了哪种溢出?
[glibc
system_clock::duration
使用glibc
存储时间点。 system_clock::duration
是chrono::nanoseconds
。
因为:
chrono::nanoseconds
计算在glibc上溢出。
我没有看到chrono::nanoseconds
中对int64_t
的任何约束,除了应该签名。
我在这里触发了哪种溢出?
当将253402210800 seconds = 253402210800000000000 nanoseconds
INT64_MAX = 922337203685477580
转换为system_clock::rep
内部的the standard draft时,system_clock::from_time_t(time_tee);
乘以253402210800
会在1000000000
内部发生[签名溢出。我认为这将完全在time_t
内部。
我认为您应该通过检查来防止溢出,例如:
system_clock::duration
问题是time_point_cast<system_clock::duration>
的时间分辨率。
此代码:
__duration_cast_impl
在__duration_cast_impl
上:
static_assert(
std::chrono::duration_cast<std::chrono::seconds>
(std::chrono::system_clock::duration::max()).count() > 253402210800
);
在system_clock
上:
#include <chrono>
#include <iostream>
int main()
{
using std::chrono::system_clock;
time_t time_tee = 253402210800;
auto tp = system_clock::from_time_t(time_tee);
time_t tee2 = system_clock::to_time_t(tp);
std::cout << time_tee << std::endl;
std::cout << tee2 << std::endl;
std::cout << system_clock::period::num << std::endl;
std::cout << system_clock::period::den << std::endl;
return 0;
}
因此,您可以看到GCC和Clang使用的MSVC prints分辨率大100倍。请注意,与253402210800
253402210800
1
10000000
相比,这也是更好的分辨率,而成本则更受时间限制。