0

Can you please explain me why the heck do I get this output? I expected to see:
2 4 2
3 9 9
Instead I have:
2 4 2
9 9 3

#include <iostream>

using namespace std;

int sq1(int);
int sq2(int&);

int main() {
    int x = 2, y = 3;

    cout<<x<<"  "<<sq1(x)<<"  "<<x;
    cout<<endl;
    cout<<y<<"  "<<sq2(y)<<"  "<<y;

    return 0;
}

int sq1(int n) {
    n *= n;
    return n;
}

int sq2(int &n) {
    n *= n;
    return n;
}
realvadim
  • 154
  • 12
  • [Cannot reproduce](http://ideone.com/1D4NOX) – πάντα ῥεῖ Jun 17 '15 at 06:29
  • @juanchopanza I'd say that the question is more of a dupe of http://stackoverflow.com/questions/10782863/what-is-the-correct-answer-for-cout-c-c since it also involves UB. The order of call to `cout` is unspecified, not undefined. It becomes undefined when you modify the parameter without sequencing. – vsoftco Jun 17 '15 at 06:37
  • @vsoftco Could be. Feel free to reopen and close the better duplicate. – juanchopanza Jun 17 '15 at 06:41
  • @juanchopanza No, I believe you're right. It should probably be just "unspecified behaviour". – vsoftco Jun 17 '15 at 06:42
  • @vsoftco I'm going to re-open because I'm not 100% sure. It is a strange combination of a function call and a value. If it involved two function calls it would be clearly unspecified. – juanchopanza Jun 17 '15 at 06:51
  • @juanchopanza there is a seq. pt. before entering `sq2`, and one at exit from `sq2`, but there is no sequencing between the other `y`'s in the `cout << ....`. However `y` is being modified only once between 2 seq. pt., so the code seems OK, just unspecified behaviour, don't you think? – vsoftco Jun 17 '15 at 07:01

2 Answers2

4

In the line

cout<<y<<"  "<<sq2(y)<<"  "<<y;

you are modifying y. There is no guarantee on the order in which each expression is evaluated.

Related: function parameter evaluation order and What is the correct answer for cout << c++ << c;?

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
1

This is undefined behaviour. There is no guarantee in which order the expression is evaluated.However in this case evaluation is done from right to left and then printed from left to right so first the y to the last is evaluated which is 3, then it is changed to 9 in the function and again printed so output is

9 9 3  
Sourav Kanta
  • 2,727
  • 1
  • 18
  • 29
  • I am not 100% sure is UB, that's what I also thought. But, as @juanchopanza mentioned in a comment, the [function call introduces a sequence point](https://en.wikipedia.org/wiki/Sequence_point). So it seems OK to modify `y` by `sq2(y)`. However, the order is not guaranteed, in which case the behaviour is "unspecified" (but not "undefined"). – vsoftco Jun 17 '15 at 06:46
  • @vsoftco I revise my statement. The sequence point would be between two function calls (which would be indeterminately sequenced.) I'm not sure what happens here! – juanchopanza Jun 17 '15 at 06:52
  • @juanchopanza I'm also reading about this now ;) Seems quite delicate. – vsoftco Jun 17 '15 at 06:54