while doing some coding, I got a rather strange behavior, which seems du to UB, but I'm asking in case I missed something obvious! I compile this code with gcc 9.3, and -O3, in debug mode there is no problems
#include <array>
#include <climits>
#include <iostream>
void integer_overflow(long long v)
{
unsigned long long uv;
// removing the following comments here make the function works!
// if (v == LONG_LONG_MIN)
// uv = static_cast<unsigned long long>(v);
// else
uv = (v < 0) ? -v : v;
std::array<char, 40> buffer;
auto last = buffer.rbegin();
*last++ = '\0';
if (v == 0)
{
*last++ = '0';
}
else
{
auto digits = 0;
do
{
auto rem = uv % 10ULL;
*last++ = rem + '0';
uv /= 10ULL;
if (uv != 0 && ++digits == 3)
{
*last++ = ','; // comment this line, the loop work!, but not the good output!!!
digits = 0;
}
} while (uv != 0);
// take care of neg values!
if (v < 0)
*last++ = '-';
}
std::cout << last.base() << std::endl;
}
int main(int argc, char** argv)
{
integer_overflow(LONG_LONG_MIN + 1); // ok
integer_overflow(LONG_LONG_MIN); // does not work
}
Output:
-9,223,372,036,854,775,807
-8
so my question how do I convert LONG_LONG_MIN to it positive counterpart in an unsigned long long ?
also is that UB as I suspect ? I think it is UB because -v for the smallest integral value on intel two's complement is probably undefined!