Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I overflow uint32_t in a temporary result?

Tags:

c

Basically what happens on a 32bit system when I do this:

uint32_t test (void)
{
  uint32_t myInt;

  myInt = ((0xFFFFFFFF * 0xFFFFFFFF) % 256u );

  return myInt;
}
like image 954
jpsalm Avatar asked Feb 02 '18 20:02

jpsalm


People also ask

Does uint256 overflow or U nderflow?

An U nderflow is similar, where if you subtract 1 from a uint8 that equals 0, it will show 255 (because uint s are unsigned in solidity, and therefore cannot be negative). Info source: Loom Network As a good practice, it seems unlikely that a uint256 will neither Overflow nor U nderflow while updating values as 2^256 is a really a huge number.

What are overflows and underflows?

Thus, certainly could be considered as a kinda-low-level language regarding variable types. What Overflows and Underflows mean? Once an uint (unsigned integer) reaches its byte size, the next element added will return the first variable element — This is more clear using an example. Let’s say we have a uint8, which can only have 8 bits.

Is uint16_t really better than integer promotion rules?

The interaction between types like uint16_t and C's integer-promotion rules are icky, but such types are still probably better than any alternative. Since Eugene's #2 is probably the most important point, I just would like to add that it's an advisory in

How to avoid overflow when using a long variable in JavaScript?

The "=" then stores the result in the unsigned long variable. To avoid overflow, use a cast, or declare counter to be long, or use a long constant as follows: Thanks, I now see why the L is used in some examples I came across.


1 Answers

Let's assume that int is 32 bits.

  1. 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.

  2. 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.

  3. (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.

  4. 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.

  1. 0xFFFFFFFF will have type int.

  2. 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.

like image 104
Dietrich Epp Avatar answered Sep 19 '22 22:09

Dietrich Epp