I have this piece of code:
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;
}
Is counter_ms.count()
guaranteed to always return a valid value? Is there any chance that count()
throws? What happens if counter_ms exceeds the size of its underlying integral type (I reckon it's long long
)? My program will run for several days in a row and I need to know what happens if/when counter_ms
gets TOO big.
Is counter_ms.count() guaranteed to always return a valid value?
counter_ms
holds a single signed integral count of milliseconds. The .count()
member function is specified to do nothing but return this signed integral value.
Is there any chance that count() throws?
This member function is not marked noexcept
for two reasons:
noexcept
has been used very sparingly in the std::lib.In the case of counter_ms
, the representation has to be a signed integral type, which of course can not throw on copy construction.
No chance that this throws.
What happens if counter_ms exceeds the size of its underlying integral type (I reckon it's long long)?
You can inspect the underlying integral type with this program:
#include <chrono>
#include <iostream>
#include "type_name.h"
int
main()
{
std::cout << type_name<std::chrono::milliseconds::rep>() << '\n';
}
Where "type_name.h" is described here. For me this program outputs:
long long
The standard spec says that this type must be a signed integral type of at least 45 bits. This gives it a range of at least +/- 557 years. You can find the actual range of your implementation of milliseconds
with this program:
#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";
}
which for me outputs:
-292277024 years
292277024 years
By coincidence, I am the one that implemented the <chrono>
implementation I am using (libc++). And the reason that the actual range is so much greater than the required minimum range is that I had trouble locating a 45 bit signed integral type, and had to settle for a 64 bit signed integral type.
When this range is exceeded, you will get the exact same behavior as signed integral arithmetic overflow (which is specified to be undefined behavior).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With