1

To handle unsigned integer wraparound issues, I am planning to use the following checks.

Addition: Performing a postcondition check to ensure that the result of the unsigned addition operation is not less than the first value

void fn(unsigned int a, unsigned int b) 
{
  unsigned int sum = a + b;
  if (sum < a) {
    // Wraparound occured. return error.
  }
  /* ... */
}

Subtraction: Performing a postcondition test that the result of the unsigned subtraction operation is not greater than the first value:

void fn(unsigned int a, unsigned int b) 
{
  unsigned int difference = a - b;
  if (difference > a) {
    // Wraparound occured. return error.
  }
  /* ... */
}

I assume these checks will works irrespective of compilers. Is there any better way to handle unsigned integer wraparound issues? I am looking for cross platform support.

Arun
  • 2,247
  • 3
  • 28
  • 51
  • 1
    That's about it for _unsigned_ math. – chux - Reinstate Monica Feb 26 '20 at 12:15
  • 1
    `better way` - The usuall question: better in what way? I would name `sum` in the second function `difference`. `sum` is misleading. – KamilCuk Feb 26 '20 at 12:15
  • 1
    Does this answer your question? [How do I detect unsigned integer multiply overflow?](https://stackoverflow.com/questions/199333/how-do-i-detect-unsigned-integer-multiply-overflow) – nivpeled Feb 26 '20 at 12:16
  • 1
    In the second case, you could simply check for `a < b` and drop the operation altogether. In the first case, is there any reason why you cannot use a larger type to hold the result? – th33lf Feb 26 '20 at 12:17
  • @KamilCuk When I searched SO, there are lot of different solutions proposed. I found this approach in SEI CERT C Coding Standard – Arun Feb 26 '20 at 12:18
  • @nivpeled That thread is talking about overflow not wraparound – Arun Feb 26 '20 at 12:22
  • @th33lf C does not specify wider types exist than `unsigned`. Example: `unsigned long long` only needs to be at least as wide as `unsigned` and at least 64-bit. Both could be 64-bit. Not common but allowed by C. Your simply `a < b` is very correct. – chux - Reinstate Monica Feb 26 '20 at 12:22

1 Answers1

0

An alternative approach for checking whether z=x+y will yield an arithmetically-correct value is to compare x with (targetType)~(promotedType)y, where (targetType) is the type of the unsigned target container, and (promotedType) is the type with which the addition would be performed. If x exceeds (targetType)~y, then the result will not fit in the target type.

To understand the casts, consider that if y is 1, then the maximum value for x should be one less than the smaller of the maximum value for the type that will receive x+y, or the type with which x+y would be evaluated. The inner promotion is needed to accommodate the case where x is larger than y, and the outer one is needed to accommodate the case where z is smaller than the type used for the addition.

supercat
  • 77,689
  • 9
  • 166
  • 211