#include <iostream>
template <typename T>
void PrintValue(T val)
{
if constexpr (std::is_signed_v<T>)
{
std::cout << "signed";
}
else
{
std::cout << "unsigned";
}
std::cout << std::endl << val << std::endl;
}
int main()
{
int a = -1;
unsigned int b = 5;
unsigned int c = 7;
auto sum = b + a;
PrintValue(sum);
PrintValue(c - b);
PrintValue(b - c);
}
The output is:
unsigned
4
unsigned
2
unsigned
4294967294
As you can see, the sum of signed and unsigned values is unsigned and the difference of two unsigned values is unsigned.
It is also an interesting fact that a signed overflow is undefined behaviour, but unsigned “wraps around”:
static_assert(std::numeric_limits<uint64_t>::max() + 1u == 0);
static_assert(std::numeric_limits<uint64_t>::max() + 2u == 1);
static_assert(std::numeric_limits<uint64_t>::max() + 3u == 2);
Multiplying maximal unsigned integer by 10:
#include <stdint.h>
#include <iostream>
#include <limits>
int main()
{
using T = uint32_t;
std::cout << std::numeric_limits<T>::max() << std::endl << std::numeric_limits<T>::max() * 10 << std::endl;
}
the output is:
4294967295
4294967286