Other than using a debugger, you can also use cout statements to help keep track of when things are called.
To kind of help myself out tracing your program I fixed a bit of the indentation and added comments as to when things are happening:
#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) {
cout << "Within A::b()" << endl;
// swap a.a, a.b
int x=a.a;
a.a=a.b;
a.b=x;
cout << "a.a.a = " << a.a << " a.a.b: " << a.b << endl;
return x;
};
int main(void) {
// sets a.a.a = 1, a.a.b = 1
A a;
// sets a.a.a = 0, a.a.b = 1
a.a.a = 0;
// a.a.a = 1, a.a.b = 0
a.b();
// check output here
cout << a.b() << a.a.b << endl;
return 0;
}
The above program results with the following output on http://cpp.sh/ :
Within A::b()
a.a.a = 1 a.a.b: 0
Within A::b()
a.a.a = 0 a.a.b: 1
10
In all, it depends on whether or not a.b() or a.a.b is resolved first when you call cout. In this case, operator precedence is undefined due to how cout works. This stackoverflow post has some good info on this.