From ea06827f2730057e84c1552603f39dc02c9f38b1 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 6 Feb 2025 20:07:05 +0100 Subject: [PATCH] docs: "Scaling overflow prevention" chapter added --- .../framework_basics/value_conversions.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/users_guide/framework_basics/value_conversions.md b/docs/users_guide/framework_basics/value_conversions.md index 5a7e2ca3..e05b5159 100644 --- a/docs/users_guide/framework_basics/value_conversions.md +++ b/docs/users_guide/framework_basics/value_conversions.md @@ -190,6 +190,28 @@ may require an addition of a potentially large offset (the difference between th which may well be outside the range of one or both quantity types. +## Scaling overflow prevention + +In the case of small integral types, it is easy to overflow the representation type for every value +besides `0` while performing simple and popular unit conversions. This is why the library prevents +such invalid conversions at compile-time both for explicit and implicit conversions: + +```cpp +quantity q1 = std::int8_t(1) * km; +quantity q2 = q1.force_in(m); // Compile-time error (1) +if(q1 != 1 * m) { /* ... */ } // Compile-time error (2) +``` + +1. Forced conversion would overflow on scaling. +2. Implicit conversion that brings arguments to a common unit before comparison would overflow on + scaling. + +In the above example, the conversion factor between `km` and `m` is `1'000`, which is larger than +the maximum value that can be stored in `std::int8_t`. Even if we want to convert the +smallest possible integral amount (e.g., `1 km`), we will overflow the quantity representation type. +We decided not to allow such conversions for safety reasons despite the value of `0 km` would work. + + ## Value conversions summary The table below provides all the value conversion functions that may be run on `x` being the