0

I recently learn the basic of C++. And i found something that i didn't get the idea. Here is the program that make me a little confuse.

       #include <iostream>

    using namespace std;

    int main() 
    {
            int m = 4, n;
            n=++m*--m;
            cout <<"m="<<m<<" and n="<<n<<"\n;
            return 0;
    }

And the output is m=4 and n=16. I thought that m=4, so ++m is 5, and --m will be 4, then n= 5*4= 20. Hence, the m=4 and n=20. I think mine is false. So i need a help. Thank you.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
Annita
  • 1
  • 1
    The operands of `*` might be evaluated in either order, it is not left-to-right as you seem to be assuming – M.M Mar 19 '17 at 13:36

4 Answers4

3

The operands of * are unsequenced relative to each other. This means that not only may they be evaluated in any order; but if each operand contains multiple sub-steps, the sub-steps of one operand might be interleaved with those of the other operand.

An example of this might be (f() + g()) * (h() + i()) . The four functions could be called in any order -- it is not required that f and g are called together, etc.

Back to your example, the following two sub-steps are unsequenced relative to each other:

  • writing the new value to m, as part of ++m
  • reading m, as part of --m

When there are two unsequenced operations on the same variable (and at least one of them is a write), it is undefined behaviour which means anything can happen (including unexpected results).

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • 1
    So, it means that not every code can happen with expected results. If there are two unsequenced operations with same variable, then it becomes undefined behaviour. I got it, Thanks! – Annita Mar 19 '17 at 14:07
1

This:

n=++m*--m;

is bad code. Replace it with something clear, such as:

n = (m + 1) * (m - 1);

The original code, for complicated reasons, may not do what you expect, so it's better not to write such code in the first place. If you want to know more about the nitty gritty details of why this is, see here: Undefined behavior and sequence points

Community
  • 1
  • 1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Yes, i know it is a bad code (for me too actually). But that is the homework that we need to follow the code. And the teacher asked me to explain what is the code mean, and why the output becomes 16. – Annita Mar 19 '17 at 13:31
  • @Annita: You can (and should) tell the teacher that the code invokes undefined behavior and is not really valid. – John Zwinck Mar 20 '17 at 03:16
0

++m means "increment m then use its value" The current call with have (m + 1) as value. m-- means "use the value of m, then decrement it" The current call with have the original value of m, and subsequent calls will have (m - 1) as value

If that makes it any clearer for you, you can also rewrite it as:

int m = 4, n;
n = (m = (m + 1)) * (m = (m - 1));
AlexG
  • 1,091
  • 7
  • 15
  • So it means that increment m (becomes 5) then we use 5 as the value. then --m means the value of m now becomes 4. But i still confuse, why the output becomes 16? – Annita Mar 19 '17 at 13:39
0

I am pretty positive the operation occurs before the increment. That is why that is happening. If you break it down like this, it should work.

The answer should be 15 because 4 + 1 is 5 and 4 - 3 is 3, thus 5 * 3 is 15. See below

    int main()
{
    int m = 4, n;
    int g;
    n = (m+1) * (m-1);
    std::cout << "m=" << m << " and n=" << n << "\n" ;
    std::cin >> g;
    return 0;
}
BunsMOO
  • 1
  • 1