Instead of using operator+(), so we've lost the expressiveness that is a hugeĪdd into the mix lossy conversions with duration_cast and it seems hopeless. Plus, when we're done, we just have some function, lossless(), that performs aĬonversion if we explicitly call it instead allowing natural implicitĬonversions, or some other function that adds a value if we explicitly call it The first place! We can't really need to implement the type just to use the Operators (but now with overflow safety) that we originally set out to use in We've had to understand and re-implement all of the logic in the duration It seems like we need to compute relationships between ratios and make decisionsĪnd check the multiplications based on that. Target_duration lossless(source_duration duration) Named duration types, supporting only the lossless conversions: template Imagine we wanted to implement an overflow-safe conversion of just the standard Relationship between their period types (where only a single multiplication is Secondly, this only handles these very particular two types with a very nice First, we had to "know" how toĬonvert between hours and nanoseconds, which kind of defeats the point. It seems to work if we test it against the limits of our standard library'sĬhoice of nanoseconds::rep: f8(0h) = 0 nsį8(2562048h) threw std::overflow_error: f8+į8(hours::max()) threw std::overflow_error: f8+īut, there are some pretty serious limitations. We could do this: nanoseconds f8(hours value) Would with integers and do a multiplication overflow check. Nanoseconds without overflowing the nanoseconds::rep type. The first hurdle is that we need to know if we can even get from hours to Conversions are another important case anyway, so we since obviously some hours valuesĬan be represented as nanoseconds or conversions would be pointless. Of course, if we make the value small enough, including by limiting the rep If(m_nanos > m_nanos.zero() & nanoseconds > m_nanos.max() - m_nanos)Īs an aside, the same problem will exist if hours uses a 32-bit rep: runtime error: signed integer overflow: 2147483647 * 3600000000000 cannot be Return _Ct(_lhs).count() m_nanos.zero() & value > m_nanos.max() - m_nanos) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPRīool operator()(const _LhsDuration& _lhs, const _RhsDuration& _rhs) const If(m_nanos > m_nanos.zero() & value > m_nanos.max() - m_nanos)Įlse if(m_nanos m_nanos.zero() & value > m_nanos.max() - m_nanos) Again, pretend this can be set in other ways, so we don't Trickier because these are signed integers: struct FooĮxplicit Foo(nanoseconds nanos = nanoseconds::max()) So, again, we can do as we would with the integers, but it's already getting Nanoseconds m_nanos = nanoseconds::max() Īnd again, we'll get into trouble: runtime error: signed integer overflow: 9223372036854775807 +ĩ223372036854775807 cannot be represented in type 'long long' Pretend this can be set in other meaningful ways so we (unknown) nanoseconds value to, the naive approach is: struct Foo If we have an existing (unknown) nanoseconds value that we want to add another For example: nanoseconds f3(nanoseconds value) When we can't be sure that value isn't already its maximum, we check first,Īnd handle the error however we deem appropriate. It's no different than the typical integer case: std::int64_t f2(std::int64_t value) Represented in type 'std::_1::chrono::duration >::rep' (aka 'long long')īut this is nothing special. With clang 7's UBSan ( -fsanitize=undefined): runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be If value is nanoseconds::max(), then this overflows, which we can confirm This function is obviously not always safe: nanoseconds f1(nanoseconds value) Representational bits that aren't required to be there by the standard. Will be std::int64_t and there are thus probably no "leftover" optional Its minimum rep size is 64-bit, which means in practice it Let's start with what I think is the "simplest" std::chrono::duration type, Please bear with me while I walk through a few cases to set the stage for my Use it practically and safely to avoid undefined behaviour. However, recently, I suddenly realized that I didn't know how to Talks on the design and use of the library. I've used std::chrono for years and have watched many of Howard Hinnant's
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |