0
#include <stdio.h>

int reverse(int);
int reverse(int x) {
  int negative = 0;
  if (x < 0)
    negative = x;
  if (negative != 0) {
    x = 0 - x;
  }
  int y = 0, temp;
  while (x > 0) {
    temp = x % 10;
    x = x / 10;
    y = (y * 10) + temp;
  }
  if (negative == 0) {
    return y;
  } else {
    return 0 - y;
  }
}
int main() {
  int x, y;
  printf("Enter your number: \n");
  scanf("%d", &x);
  y = reverse(x);
  printf("The reversed number is: %d\n", y);
  return 0;
}

This program reverses a signed integer. I was unable to check if the revered integer y, is out of bounds. I'm not able to attain clarity on the topic of overflow. If I ask the compiler using scanf to scan an integer and enter an integer that is out of range of the integer, what will happen? Does the value change as it is stored?

Stargateur
  • 24,473
  • 8
  • 65
  • 91
  • You need to contrive an example and try it. This is a question you can answer on your own through trial and error. – nicomp Aug 26 '18 at 12:13
  • 1
    "This program reverses a signed integer." what does that mean ? – Stargateur Aug 26 '18 at 12:15
  • 1
    @nicomp: Trial and error reveals only what one C implementation does (or as many implementations as a tried), not what the C standard says. – Eric Postpischil Aug 26 '18 at 12:38
  • @Stargateur: it is clear from the code they are reversing the significant digits in the decimal numeral for the number. – Eric Postpischil Aug 26 '18 at 12:43
  • @EricPostpischil I "should" not have the need to read the code to understand ;) but reverse a number don't make a lot of sense in math so I ask clarification about this information. – Stargateur Aug 26 '18 at 13:03
  • @EricPostpischil You are correct, but that does not advance the discussion. – nicomp Aug 26 '18 at 22:00
  • @nicomp: The point is your comment misleads the OP and others. When seeking to ascertain what can happen when `scanf` encounters a numeral that is out of range, one ought to look to the C standard and the documentation of the compiler. Telling people that they should figure this out by experimenting is bad advice. – Eric Postpischil Aug 26 '18 at 22:59

2 Answers2

1

You seem to have two different questions regarding overflow.

  1. How to detect overflow in integer arithmetic?
  2. How to detect ovetflow in conversion functions like scanf?

The answers are as follows.

  1. There's no generic way, you have to do it on a case by case basis. For example, if y <= INT_MAX / 10, you can be sure y * 10 will not overflow. Same thing about ... + temp.
  2. scanf and friends do not have any way to protect you from overflow, other than limiting field width and thus input range (but you cannot limit the range exactly to INT_MAX if you are reading a decimal). If the scanned value doesn't fit into the destination type, the behaviour is undefined. The only way to safely convert a string with the exact range is with strtol and friends. These functions detect overflow and set errno accordingly.
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

In standard C, overflow is an exceptional condition and behaviour is then undefined per standard. From draft n1570 for C11, 6.5 Expressions § 5:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

That means that you cannot process overflow in a way that would be defined per standard. That being said, most compilers simply keep the low order bits of the result that can fit in the type representation and ignore the highest order bit(s). This is what MSVC, gcc, and clang do.

From now on, I will assume that your system uses the int32_t (resp. int16_t or int64_t) for signed int and ignores overflow. It is not mandated per standard but is common enough and is probably what your system does.

There are 2 possible overflows in your code. First is the scanf function: as said by @n.m., nothing is said for the behaviour of this family of function if the input sequence does not fit in the type. I will assume that the submitted number is acceptable as a signed int (between INT_MIN and INT_MAX). Anyway, it is trivial to have it detected by the user: just display x: if it is not the just typed number, then an overflow occured.

Second is here:

y = (y * 10) + temp;

Here again it is easy to test for overflow, by doing the reverse operations and controling that all was fine:

int next = (y * 10) + temp;
if ((next < 0) || (y != (next - temp) / 10)) {
    // an overflow occured...
    ...

In theory, nothing can guarantee that negating a positive int is a valid negative int, but this is true for the intXX_t types, so that should be enough to detect an overflow in the reverse function.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks for the answer. Yes, I'm trying to discard the input and check for the overflow in the in reversing operation. – Udhay Sankar Aug 26 '18 at 13:56