-2

I'm just write this code but I don't know how it works.

Why the value of k will be negative? How?

#include<iostream>
using namespace std;
int main()
{
    int k=1,j=0;
    while(k>j)
    {
        j=k;
        k++;
    }
    cout<<j<<"\n"<<k;
}

it shows the range of an integer

Baran
  • 97
  • 1
  • 11
UZAIR69
  • 7
  • 1
  • 5
    `#include using namespace std;` is not C. Please don't add the C tag. – NathanOliver Jun 12 '19 at 12:48
  • 11
    signed overflow is undefined behavior. – Jarod42 Jun 12 '19 at 12:49
  • Related: https://stackoverflow.com/questions/16188263/is-signed-integer-overflow-still-undefined-behavior-in-c – Damien Jun 12 '19 at 12:51
  • [**Why is “using namespace std;” considered bad practice?**](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Andrew Henle Jun 12 '19 at 12:52
  • @NathanOliver code syntax is C++ but its basically C language that is why i tag bot c and c++ – UZAIR69 Jun 12 '19 at 13:01
  • 2
    @UZAIR69 If you can't compile it in a C compiler, which you can't, then it is not C code. C and C++ share a lot of the same syntax so we care on what language the code is compiled against, not how it looks. – NathanOliver Jun 12 '19 at 13:03
  • @AndrewHenle sorry ! im a beginner programm , i just only learn coding.im not a professional programmer – UZAIR69 Jun 12 '19 at 13:04

5 Answers5

6

int has a limited range. At some time, k++ overflows this limit. After that point, the behavior is undefined and anything can happen.

If the compiler is very conservative, then it will simply overflow to negative values (particularly in the near-ubiquitous case where int is 2's complement), but that is not guaranteed. In that case, the while loop will terminate.

Look at what gcc does with and without optimization. Both behaviors are legal according the standard, as signed overflow behavior is undefined.

With optimization (infinite loop):

main:
.L2:
        jmp     .L2

Without optimization: Prints:

2147483647
-2147483648

Again, anything can happen, not only the above two behaviors. Signed overflow is undefined.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
Michael Veksler
  • 8,217
  • 1
  • 20
  • 33
  • 1
    @Bathsheba Good point, as signed-magnitude (or 1's complement) may do something different in case of an overflow. Also, overflow might trap, which I forgot to mention. – Michael Veksler Jun 12 '19 at 13:08
  • Signed magnitude and 1's complement tend to clamp. Although I am revealing my age here... – Bathsheba Jun 12 '19 at 13:09
3

The behaviour of your code is undefined due to the overflow of a signed integral type.

There is no defined way by which k can become negative. Because of that, a good compiler (optimising gcc for example) may well compile while(k > j) to, effectively, while(true).

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Your code will keep on incrementing the variable k because the condition k > j is true. At some point k will get equal to the maximum int value supported on your system. When you do k++ in the next loop, the result is not representable as an int. This is called integer overflow and according to the standard, the code has undefined behavior. As it is undefined behavior we can't say what will happen in general - it is system specific.

On many system the result of incrementing the maximum intvalue will result in the minimum int value. On such systems your code is equivalent to the code:

#include<iostream>
#include <limits>

int main()
{
  int j = std::numeric_limits<int>::max();
  int k = j + 1;
  std::cout << j << std::endl << k << std::endl;
  return 0;
}

On my system the output is:

2147483647
-2147483648

But do not expect this to hold for all systems. On other systems the program may crash, or enter an endless loop or do whatever... it is undefined by the standard.

A better way to write the code so that it will work on all systems is:

#include<iostream>
#include <limits>

int main()
{
  int j = std::numeric_limits<int>::max();
  int k = std::numeric_limits<int>::min();
  std::cout << j << std::endl << k << std::endl;
  return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
-1

In your code, k is always one greater than j at the time of the test, until it exceeds the maximum value that can be represented by an int. Then (in your case, as evidenced by your question -- it is indeed not defined by the standard) it rolls over to the other end of the range: the maximum negative value.

L. Scott Johnson
  • 4,213
  • 2
  • 17
  • 28
-1

the while goes on until j is 2147483647

2147483647 +1 = -2147483648

the integer 32bit overflows and become negative, stopping the while.

  • 1
    It's not that helpful: it's only one possibility (albeit a likely one on the current crop of desktop PCs). – Bathsheba Jun 12 '19 at 13:09
  • 1
    Uhm... I'm sure that's what happened in OP case, also I never seen a compiler do it a different way. Rollover can be very beneficial especially in microcontrollers where abusing side effects can save instructions. Still, I never tried compiling with very aggressive settings. I think O2 should pretty much garantuee this result. – 05032 Mendicant Bias Jun 12 '19 at 13:12