-7

Giving this code:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int k, x;

    while(k > x-3) {
         k--;
         // cout << "x = " << x << "\n";
    }
    x++, k--;

    int aux = abs(k-x);
    cout << aux;
}

When we run it, it always pops up a constant x (x = 50) and the absolute value between the integer k and the x is always 5. Can you please explain me why and how does this works?

Alex C
  • 15
  • 2
  • 13
    Actually undefined behavior because `k` and `x` are not initialized. – Matthieu Brucher Feb 26 '19 at 09:23
  • So what is the explanation of this program? – Alex C Feb 26 '19 at 09:24
  • 4
    You're using `k` and `x` uninitialized, so this is undefined behavior anyway. That aside (assuming they are initialized to a default value), you're not taking any input or random values, so why would you expect a different result every time? – Blaze Feb 26 '19 at 09:24
  • But if they were defined with a value of `k` far greater than `x`, you end up after the loop with `k = x-3`, then you increment them, and the result would be `3`. If `k` starts below `x-3`, then the result can be anything. – Matthieu Brucher Feb 26 '19 at 09:25
  • When you wake up tomorrow you'll see different constant value, unless that address is being over written – Inder Kumar Rathore Feb 26 '19 at 09:27
  • 2
    @AlexCiornei _"So what is the explanation of this program?"_ There's no reasonable explanation for the behavior of _undefined behavior_, at best for a very specific compiler of a very specific version. – πάντα ῥεῖ Feb 26 '19 at 09:27
  • Possible duplicate of [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Raedwald Feb 26 '19 at 09:28
  • This problem was given in an admission to a faculty, so I'm trying to understand why this is the answer and not another. Basically it says so: "in the next sequence of code, the x and k are integers. Before executing it, k is greater than x. Please say what is the value of the expression abs(k-x) at the end of the execution". – Alex C Feb 26 '19 at 09:29
  • 4
    So it's an ill-posed problem because the code as is is UB, but they expect to set `k` and `x`. – Matthieu Brucher Feb 26 '19 at 09:30
  • I see. Got it! Thanks a lot! – Alex C Feb 26 '19 at 09:31

3 Answers3

4

With the constraint of "k is greater than x", this piece of code here

while(k > x-3) {
     k--;
     // cout << "x = " << x << "\n";
}

Will decrease k to be 3 less than x.

The next line, x++, k++; increases them both by 1, but it doesn't change the result. k is still 3 smaller than x.

k-x is -3 and abs(k-x) is 3, hence why the program always prints 3. Assuming, of course, that both k and x are initialized and that k is bigger than x. The program as it is posted with k and x uninitialized exhibits undefined behavior, so there's no guarantee on what is going to happen. Also, as Aconcagua points out, if x is smaller than INT_MIN + 3, that also leads to undefined behavior.

Blaze
  • 16,736
  • 2
  • 25
  • 44
0

Matthieu and πάντα ῥεῖ are correct: Ths is classic undefined behavior. (One rationale for making it undefined and not simply unspecified or implementation defined is that some architectures have flags for uninitialized registers and would trap.) A compiler is actually free to compile it to an empty program: Reading an uninitialized variable can result in anything — and nothing is a subset of anything. All subsequent code after the undefined behavior is "tainted" by the preceding error and can be omitted. Note that different architectures and different compilers, possibly even different C standard libs (with the same compiler!) may give different results; even a different compiler flag (concerning optimization or function call conventions) may change this undefined behavior.

(The rest of this answer applies to the version of the question where the line after the loop read x++, k++; (instead of k-- as it is now).)

But you have encountered a consistent behavior, and the question is why it is consistent. The first assumption is that the compiler does not simply generate code to output "5", (which it could, legitimately) but actually "naively" generates machine code that corresponds to the C statements. We'll reason along the statements.

Then the behavior indicates that the memory locations where x and k reside are containing values which make k > x -3 false right away. (Otherwise, k would be decremented until the difference is 3, not 5).

If the condition is false, the variable difference will not change; from that we can conclude that it was 5 from the start with x-k == 5. If you omit the abs(), the output should be -5.

The reason the variables have these consistent intial values may be connected to things the operating system or C runtime environment do at program startup, like initializing the standard streams. Try using printf instead of cout and see if the result changes.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • The answer concerned a version of the question when the code read `x++, k++;`. As it now stands, 5 is the expected outcome with initial values for which `k >= x-3` is true, including the probably-not-uncommon case that both are 0. In that case Blaze's answer is correct. It is perhaps worth noting that an output of 5 is only possible if `k >= x-3`, if I'm not mistaken. (After changing `k++` to `k--` in the question.) My hunch is that the question aimed at that insight. – Peter - Reinstate Monica Feb 26 '19 at 10:51
0

I really think you should try two arbitrary numbers. For example , imagine we are using k= 10 & x=8. Your loop will look like: While(10>5) 10-1=9 ... and so on, until K is not greater than (X-3). You will get k=5, and x is the same value,8. After the while loop you decrement k, and increment x, so k=4 and x=9. Abs(k-x) = 5.

If you want the more theoretical explanation, the loop will grant that the difference between your two variables is 3, the X will be greater than K. As after the loop you decrement K and increment X , the diference between them will ALWAYS be 5.