2
#include <iostream>
using namespace std;
class A {
public:
    A() { a.a = a.b = 1; }
    struct { int a,b; } a;
    int b(void);
};
int A::b(void) { 
    int x=a.a;
    a.a=a.b;
    a.b=x; 
    return x;
};
int main(void) {
    A a;
    a.a.a = 0;
    a.b();
    cout << a.b() << a.a.b << endl;
return 0;
}

I am currently practicing for a C++ certification and I came across this question. I found it strange that after the cout, if I print only the a.a.b value, it prints 1, but the code as it is displays 10, so the value of a.a.b is considered 0. From the research I've done online it seems that this is undefined behaviour as there is no guarantee that in the cout call the compiler will first evaluate the a.b() call and then evaluate the a.a.b value. Is there a definite order in which the compiler should evaluate the expressions in this cout?

JDGross
  • 83
  • 1
  • 8
  • 8
    [Order of evaluation](https://en.cppreference.com/w/cpp/language/eval_order) rule has evolved in C++17. – Jarod42 Oct 15 '20 at 14:44
  • 2
    note that there are more nuances than just correct as expected and undefined behavior. This is certainly not UB, see here for the details: https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – 463035818_is_not_an_ai Oct 15 '20 at 14:45
  • Hmm! Both MSVC and clang-cl give `11` as the output. – Adrian Mole Oct 15 '20 at 15:03
  • @AdrianMole: State C++ version, prior to C++17, order of evaluation is undetermined, so 10 or 11 are possible, Since C++17, 10 is guaranteed. – Jarod42 Oct 15 '20 at 16:26
  • 1
    @Jarod42 I tried with both `std:c++17` and `std:c++14`. If the order of evaluation is guaranteed in C++17 (left-to-right), then `11` is the correct output, is not? – Adrian Mole Oct 15 '20 at 16:27
  • Going through the lines in `main`: After `A a;` then `.a == 1` and `.b == 1`; after `a.a.a = 0;`, then `.a == 0` and `.b == 1`; after `a.b();` (did you forget this line?) then `.a == 1` and `.b == 0`. Then, the *first* operation (`a.b()`) in the `cout` line, will return `1` and set `.b` to `1` (the *second* output). – Adrian Mole Oct 15 '20 at 16:34
  • Indeed 11 for C++17, too quickly read code. (using `std::swap` would be more readable). – Jarod42 Oct 15 '20 at 16:36

0 Answers0