This code gives the meaningful output
#include <iostream>
int main() {
unsigned int ui = 100;
unsigned int negative_ui = -22u;
std::cout << ui + negative_ui << std::endl;
}
Output:
78
The variable negative_ui
stores -22
, but is an unsigned int
.
My question is why does unsigned int negative_ui = -22u;
work.
How can an unsigned int
store a negative number? Is it save to be used or does this yield undefined behaviour?
I use the intel compiler 18.0.3. With the option -Wall
no warnings occurred.
Ps. I have read What happens if I assign a negative value to an unsigned variable? and Why unsigned int contained negative number
How can an
unsigned int
store a negative number?
It doesn't. Instead, it stores a representable number that is congruent with that negative number modulo the number of all representable values. The same is also true with results that are larger than the largest representable value.
Is it save to be used or does this yield undefined behaviour?
There is no UB. Unsigned arithmetic overflow is well defined.
It is safe to rely on the result. However, it can be brittle. For example, if you add -22u
and 100ull
, then you get UINT_MAX + 79
(i.e. a large value assuming unsigned long long
is a larger type than unsigned
) which is congruent with 78 modulo UINT_MAX + 1
that is representable in unsigned long long
but not representable in unsigned
.
Note that signed arithmetic overflow is undefined.