2

Here is my problem:

int addsomeStuff(std::ostream &cout, int b) {
    cout << b;
    return 2;
}

int main() {
    int a = 1;
    cout << a << addsomeStuff(cout, 3) << endl;
    return 0;
}

Output: 312

Can Someone explain me the Output, i would expect the output more like 132 why is the compiler runs first the Function before making the operator.

How i run into this issue: I have a container class which can hold data inside an bytearray. Somehow the 'container.WriteConvert(..);' get inserted into bytearray before the integer called 'a'. Does anyone have an explaintation for that.

I could make the WriteConvert static or add an extra Line which would fix this problem, instead of returning an Container& but i am kinda intrested whats the reason the Compiler puts this in this order.

    int a = 2;
    Container container;
    container << a << container.WriteConvert("TestString");

    int b = 0;
    container >> b;
    cout << b;

    // The ouput of 'b' is some stupid Data which is caused by WriteConvert.

The Reason i didnt wrote this WriteConvert static or outside of the Container class has some reason. I have also ReadConvert which i dont want to have multiline. If someone has another idea i am open for other solutions, without increasing line amount.

    int b = 0;
    string output
    container >> b >> container.ReadConvert(output);
    cout << b;
Daros
  • 43
  • 3

1 Answers1

0

Pre C++17, the order of evaluation of the chained operator arguments' was unspecified. That means the execution could've first evaluated addsomeStuff(cout, 3) call (thus printing 3 first) and then proceed to print a and the returned value of addsomeStuff(cout, 3).

With C++17, the order of evaluation is well defined - left to right. That means that if your compiler correctly implements the C++17 standard, the only possible output is 132.

If you are stuck with a pre C++17 standard, you would need to first evaluate all the arguments and then use them in chained operator call or don't use chained operator calls:

int main() {
    int a = 1;
    cout << a;
    cout << addsomeStuff(cout, 3) << endl;
    return 0;
}

The former approach may alter the behaviour, but will be well-defined.

Fureeish
  • 9,869
  • 3
  • 23
  • 46
  • Thanks really helpfull, do you maybe have an link for the documenation? – Daros Sep 14 '19 at 22:54
  • @Daros it's pretty hard for me to gather every relevant part of the standard to provide such documentation, but if you want to read a little more about this, I highly suggest reading [this question and answers](https://stackoverflow.com/questions/38501587/what-are-the-evaluation-order-guarantees-introduced-by-c17). – Fureeish Sep 14 '19 at 22:58
  • @Daros [Undefined behavior and sequence points](https://stackoverflow.com/q/4176328/995714) – phuclv Sep 15 '19 at 02:25