Xiaolong
Xiaolong

Reputation: 259

Help? Why the output is like this?

#include <iostream>
using namespace std;

int a = 8;

int g()
{
    a++; 
    return a - 1;
}

int f()
{
    a++;
    return a;
}

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

Output is "11 11 18"

Upvotes: 3

Views: 131

Answers (6)

paxdiablo
paxdiablo

Reputation: 881103

For this particular result, g() + f() is being evaluated first which will result in a eventually being incremented to 10 and the result being 18. This is the case regardless of whether the g() or f() bit of that sum is done first. Doing g() first gives 8+10, otherwise it's 9+9.

Then f() is evaluated, setting a to 11 and returning 11.

Then g() is evaluated, setting a to 12 and returning 11.

In other words, it's calling the right-most bits of the cout first and proceeding left.

Now you'll notice the phrase "for this particular result" in my ramblings above. Whether this is mandated by the standard, I don't know for sure (meaning I couldn't be bothered looking it up at the moment), but I very much doubt it, based on experience.

So, while it's actually outputting the items in the correct order, the side effects can be different depending on a large number of things. That's one reason why global variables (or, more correctly, side effects on them) are rarely a good idea and you should probably rethink your use of them :-)

Upvotes: 4

user2100815
user2100815

Reputation:

The order of evaluation of functions is unspecified in C++. In the code:

cout << g() << " " << f() << " " << g() + f() << endl;

The compiler could emit code to call f(), f(), g(), g() and then add the results. Or it could do something else.

This is nothing specific to use with cout, BTW - if you write code like this:

x = a() + b() * c();

There is no guarantee about which order a, b and c will be called in. This is one of the many reasons that global variables are A Bad Thing - you often cannot predict how functions that change them will be called.

Upvotes: 9

Jordonias
Jordonias

Reputation: 5848

cout << g() << " " << f() << " " << g() + f() << endl;

same as

cout.operator<<(operator<<(operator<<(operator<<(operator<<(operator<<(endl), g() + f()), " "), f()), " "), g());

The order the functions are called is why this occurs.

Upvotes: 0

ralphtheninja
ralphtheninja

Reputation: 132988

It has to do with order of evaluation. In this case g() + f() is evaluated first, thus giving 8 + 10 = 18. After this a == 10 and f() is evaluated which gives 11 and sets a to 11 etc

Upvotes: 4

amit
amit

Reputation: 178411

a is a global variable and thus is being accessed by all.
in addition, operator<< is being accessed from right to left, so:
g() + f() = 8+10=18 (a after it is 10)
f() = 11 and a is 11
g() = 11 and a is 12

Upvotes: 2

Mark Ransom
Mark Ransom

Reputation: 308111

The order of execution is not guaranteed unless there is a sequence point in the expression. If you want to know the order here you have to break it into separate statements.

cout << g() << " ";
cout << f() << " ";
int temp = g();
temp += f();
cout << temp << endl;

Upvotes: 3

Related Questions