I was reading the C Standard the other day, and noticed that unlike signed integer overflow (which is undefined), unsigned integer overflow is well defined. I\'ve seen it us
I would suggest always having an explicit cast any time one is going to rely upon unsigned numbers wrapping. Otherwise there may be surprises. For example, if "int" is 64 bits, code like:
UInt32 foo,bar;
if ((foo-bar) < 100) // Report if foo is between bar and bar+99, inclusive)
... do something
may fail, since "foo" and "bar" would get promoted to 64-bit signed integers. Adding a typecast back to UInt32 before checking the result against 100 would prevent problems in that case.
Incidentally, I believe the only portable way to directly get the bottom 32 bits of the product of two UInt32's is to cast one of the ints to a UInt64 prior to doing the multiply. Otherwise the UInt32's might be converted to signed Int64's, with the multiplication overflowing and yielding undefined results.
To put it shortly:
It is perfectly legal/OK/safe to use unsigned integer overflow as you see fit as long as you pay attention and adhere to the definition (for whatever purpose - optimization, super clever algorithms, etc.)
Since signed numbers on CPUs can be represented in different ways, 99.999% of all current CPUs use twos-complement notation. Since this is the majority of machines out there, it is difficult to find a different behaviour although the compiler might check it (fat chance). The C specs however must account for 100% of the compilers so have not defined its behaviour.
So it would make things more confusion, which is a good reason to avoid it. However, if you have a really good reason (say, performance boost of factor of 3 for critical part of code), then document it well and use it.
siukurnin makes a good point, that you need to know when overflows will occur. The easiest way to avoid the portability issue he described is to use the fixed-width integer types from stdint.h. uint32_t is an unsigned 32-bit integer on all platforms and OSes, and won't behave differently when compiled for a different system.
Unsigned integer overflow (in the shape of wrap-around) is routinely taken advantage of in hashing functions, and has been since the year dot.
If you use it wisely (well commented and readable), you can benefit from it by having smaller and faster code.