Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this unsigned int holding more data than it has memory for?

An unsigned int can only hold 32 bits of data. Why doesn't the compiler give an error when I assign a larger value to it than what it can hold?

I have tried other various values and it still gives no error.

int main()
{
    unsigned int mem = 0x89678456543454345934;
    cout << mem;

    return 0;
}
like image 910
wazeeer Avatar asked May 19 '15 21:05

wazeeer


People also ask

Does unsigned int use less memory?

An n-bit unsigned variable has a range of 0 to (2n)-1. When no negative numbers are required, unsigned integers are well-suited for networking and systems with little memory, because unsigned integers can store more positive numbers without taking up extra memory.

How much memory does an unsigned int take?

The int and unsigned int types have a size of four bytes.

What happens when unsigned int overflows?

"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."

What is the point of unsigned int?

Unsigned integers are used when we know that the value that we are storing will always be non-negative (zero or positive). Note: it is almost always the case that you could use a regular integer variable in place of an unsigned integer.


1 Answers

That's because 0x89678456543454345934 is greater than std::numeric_limits<unsigned_int>::max(). However, unsigned types wrap around their maximum value, so if the right hand side is representable by an integer type you have well defined behaviour. In that case the result is 0x89678456543454345934 mod std::numeric_limits<unsigned_int>::max.

EDIT

The right hand side of your assignment is an integer literal. To represent it, the compiler uses the first type (ordered wrt its size) in which the integer literal can fit. If there is no such type, then the program is ill-formed. The decimal value of your constant is:

648873758694578209446196L

On my machine, for both clang++ and g++ std::numeric_limits<unsigned long long>::max() is 18446744073709551615, which is smaller than your constant. It seems that your program is then ill-formed, unless the compiler uses more than 64 bits to represent unsigned long long, which I highly doubt. As @juanchopanza remarked, clang++ refuses to compile the code, with the error

error: integer constant is larger than the largest unsigned integer type

g++ however goes ahead and compiles it, emitting only a warning

warning: large integer implicitly truncated to unsigned type

The warning is quite confusing, as it refers to the right hand side, not to the further conversion to unsigned int, for which you get

warning: large integer implicitly truncated to unsigned type [-Woverflow]

On my machine std::numeric_limits<unsigned int>::max() is 4294967295, and therefore 648873758694578209446196L % 4294967295 is 3633002191L. However when I run your program I get 1412716852. This happens because the program is ill-formed, and unfortunately the compiler does not emit an error (it is not mandated by the standard) but only a warning.

like image 142
vsoftco Avatar answered Sep 18 '22 10:09

vsoftco