An unsigned int literal outside bounds

132 views Asked by At

If I define a variable of the unsigned int type and initialize it with a value outside its bounds, it uses modulo and assigns itself a value in its range, right?

For example:

unsigned int a = 4294967298;
std::cout << a << std::endl;

will print 2.

However, if instead of that, I write:

std::cout << 4294967298u << std::endl

it prints 4294967298 and not 2.

Why is that?

I thought we were doing pretty much the same thing in both of the examples.

Is it because in the second example, the literal is not an int, but long or something by default, and we've converted it to unsigned long by adding u as a suffix? In that case, how do we use it as an unsigned int literal?

2

There are 2 answers

0
Remy Lebeau On BEST ANSWER

4294967298 without any suffix is either an int, long int, or long long int, depending on which one is the smallest type that the compiler can use to hold the full value without wrapping/truncating it. Assigning such a type to an unsigned int variable will potentially wrap the value.

4294967298u with the u suffix is either an unsigned int, unsigned long int, or unsigned long long int (again, depending on the compiler implementation). It is not a (long) (long) int that gets converted into an unsigned (long) (long) int.

See Integer literal on cppreference.com for details on what suffixes are available and which data types are used.

operator<< is overloaded for all signed and unsigned integer types, so it is able to print whatever value is being held by whatever type is passed to it. In your first example, the value is already affected before operator<< ever sees it. In the second example, the value is printed as-is.

0
273K On

4294967298u is unsigned long, you can see it on cppinsights.io, because the type of the value 4294967298u depends on its value - a compiler picks a type that can fit a typed value, but a picked type may not be narrower than unsigned int.

  std::operator<<(std::cout.operator<<(4294967298UL), '\n');