Basically what happens on a 32bit system when I do this:
uint32_t test (void) { uint32_t myInt; myInt = ((0xFFFFFFFF * 0xFFFFFFFF) % 256u ); return myInt; } Let's assume that int is 32 bits.
0xFFFFFFFF will have type unsigned int. There are special rules that explain this, but because it is a hexadecimal constant and it doesn't fit in int, but does fit in unsigned int, it ends up as unsigned int.
0xFFFFFFFF * 0xFFFFFFFF will first go through the usual arithmetic conversions, but since both sides are unsigned int, nothing happens. The result of the multiplication is 0xfffffffe00000001 which is reduced to unsigned int by using the modulo 232 value, resulting in the value 1 with type unsigned int.
(unsigned int)1 % 256u is equal to 1 and has type unsigned int. Usual arithmetic conversions apply here too, but again, both operands are unsigned int so nothing happens.
The result is converted to uint32_t, but it's already unsigned int which has the same range.
However, let's instead suppose that int is 64 bits.
0xFFFFFFFF will have type int.
0xFFFFFFFF * 0xFFFFFFFF will overflow! This is undefined behavior. At this point we stop trying to figure out what the program does, because it could do anything. Maybe the compiler would decide not to emit code for this function, or something equally absurd.
This would happen in a so-called "ILP64" or "SILP64" architecture. These architectures are rare but they do exist. We can avoid these portability problems by using 0xFFFFFFFFu.
Unsigned integer overflowing means you can try to put a value greater than the range of what it can hold - but it will wrap and will put a number modulo UINT32_MAX+1. In fact in this case also that will happen provided you append the U or u with the integer literals. Otherwise integer literals are consideredwhen turns out to be signed (As you didn't specify anything), will result in overflow due to multiplication and signed integer overflow which is Undefined Behavior.
Again back to the explanation, here when you are multiplying this (ensuring that they are unsigned it (the result) will wrap in UINT32_MAX+1 by wrapping in it is meant that if it is bigger than uint32_t then the result will be applied over modulous of UINT32_MAX) and then we apply modulo operation with 256u and then that result is stored in uint32_t and returned from the method. (Note that the result of multiplication if overflows will be at first taken as modulo of UINT_MAX+1)
int happens to have width 64 bits on the target platform, then 0xFFFFFFFF would be signed?u or U suffix may be either signed or unsigned -- see your own link. It depends on the types that can represent the value.int they will be stored in one if not then they will be in unsigned int and so on..int, unsigned int, long, unsigned long, long long, unsigned long long..which ever comes first and capable of storing it
luis not necessary,uby itself is fine.lis not necessary to ensure that the constants each have the specified value, and it does not ensure that the multiplication of the two constant values will not overflow.unsigned long, which makes usinglpointless. Withull(forcing both operands of the multiplication to beunsigned long long), you'd have a guarantee that the product fits.unsigned longcan be as small as 2^32 - 1, and that bound is extremely common in practice. Where it applies, theldoes nothing to prevent the OP's multiplication from overflowing.