]> code.bitgloo.com Git - clyne/constexpr-to-string.git/commitdiff
Fixed potential bug with -MINIMUM_VALUE
authorEnilPajic <epajic1@etf.unsa.ba>
Fri, 26 Jun 2020 19:25:39 +0000 (21:25 +0200)
committerGitHub <noreply@github.com>
Fri, 26 Jun 2020 19:25:39 +0000 (21:25 +0200)
Original code had something like `N < 0 ? -N : N` which could fail if `N` has minimum value of appropriate type. For example, in original code this could fail:
```cpp
const long long int LL_MIN = std::numeric_limits<long long int>::min(); //probably: -9223372036854775808
static const char *number = to_string<LL_MIN, 10>;
```

Also note that this code relies on "modulo on negative first operands" which was implementation defined in C++03 and before, but with C++11 and later it is defined by standard (see `ISO14882:2011(e)`), and this code anyway targets C++17 so we're safe here.

to_string.hpp

index 116cdd8f8c498d31b57e6d9fbb1a7626e34c3999..611725855732c39b6a3bdc6ba304bbb23a4b09b7 100644 (file)
@@ -23,7 +23,7 @@ struct to_string_t {
     // fits to the number perfectly.
     char buf[([] {
                   unsigned int len = N >= 0 ? 1 : 2;
-                  for (auto n = N < 0 ? -N : N; n; len++, n /= base);
+                  for (auto n = N; n; len++, n /= base);
                   return len;
              }())];
 
@@ -33,8 +33,8 @@ struct to_string_t {
     constexpr to_string_t() {
         auto ptr = buf + sizeof(buf) / sizeof(buf[0]);
         *--ptr = '\0';
-        for (auto n = N < 0 ? -N : N; n; n /= base)
-            *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % base];
+        for (auto n = N; n; n /= base)
+            *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(N < 0 ? -1 : 1) * (n % base)];
         if (N < 0)
             *--ptr = '-';
     }