-2

I have created two functions and return the value to main part.

#include <iostream>
using namespace std;
int a =8;
int g(){a++; return a-1;}
int f(){a++; return a;}

int main (){
    cout << g()+f()<<endl;
    return 0;
}

I don't why the output would be 18 but not 17. I was wondering if anyone can explain this in detail for me? Thanks for your help

bud-e
  • 1,511
  • 1
  • 20
  • 31
May
  • 3
  • 3
  • 1
    f:8+1; g:9+1-1; g+f:18; Do not remember which function will be call first, but result will be the sane in this case – Neska Dec 03 '14 at 09:27
  • Please clarify your question. What do you expect (and why) and what do you get? – juanchopanza Dec 03 '14 at 09:27
  • Thanks for your help. I have got it right now – May Dec 03 '14 at 09:28
  • because in c++ the order of function parameter evaluations (is not defined](http://stackoverflow.com/a/2934909/847349). Try `g()+f()` and you get quite another answer. It's just a bad idea to return and mutate a variable from the same function. What would you expect? Check out this too: http://herbsutter.com/2014/12/01/a-quick-poll-about-order-of-evaluation/ – Dmitry Ledentsov Dec 03 '14 at 09:31
  • @May what have you gotten right now? – Dmitry Ledentsov Dec 03 '14 at 09:31
  • @Dmitry Ledentsov I understand the process and the reason why the program generate 18 but not 17. Thanks for your help. – May Dec 03 '14 at 09:34
  • @DmitryLedentsov, Refrain from saying undefined for something that is unspecified. One has worse consequences. – chris Dec 03 '14 at 09:34
  • I refer you to my first comment: please state clearly what you get, and what you expect. Your question is quite unclear as it stands. – juanchopanza Dec 03 '14 at 09:48
  • @chris, indeed. Will take care about wording next time – Dmitry Ledentsov Dec 03 '14 at 09:59

3 Answers3

5

First of all, note that the arguments to operator + are not sequenced, which means g() and f() can be evaluated in two orders, g() followed by f(), or f() followed by g(). It just happens that in this particular case, both of these orderings give a the same result, 18, achieved in different ways:

  • g() followed by f(): g increments a to 9, and returns 8. f increments a to 10 and returns 10. The sum is 18.

  • f() followed by g(): f increments a to 9 and returns 9. g increments a to 10 and returns 9. The sum is 18.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Thanks for your detailed explanation. Do you mean that if there is different order of functions, an entirely different result will be generated? – May Dec 03 '14 at 09:40
  • @May Well, here you get 18 regardless of the order. But in principle, yes, you can't rely on the ordering. It is even worse if you pass expressions that are not function calls. If you say something like `a++ + ++a` then you get *undefined behaviour*, which means your program is free to do whatever it likes. – juanchopanza Dec 03 '14 at 09:43
1

This is undefined behavior. The two function calls can be evaluated by the compiler in any order.

From standard: N3797, 1.9, paragraph 15

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

Laura Maftei
  • 1,863
  • 1
  • 15
  • 25
0

As variable 'a' is declared globally, its scope is throughout the program. In g(), a is incremented to 9 and a-1 is returned i.e., 8. The return statement doesn't affect the value of a. In f(), a is incremented to 10 and returned. Now, the print statement will be like this cout<<8+10; and prints 18 to the console.