Ok, I'll add some more mystery. Here's my take:
#include
using namespace std;
class Loo
{
public:
static int x;
static int y;
static int z;
int a;
int b = ++y;
int c;
Loo() : a(++x), c(b+(++z)) {}
Loo(int i) : a(++b), b(++i), c(++b) {}
void show(){ cout << "a " << a << ", b " << b << ", c " << c << endl;}
static void show_(){ cout << "x " << x << ", y " << y << ", z " << z << endl;}
};
int Loo::x = 0;
int Loo::y = 0;
int Loo::z = 0;
int main()
{
Loo::show_();
Loo l;
l.show();
Loo::show_();
Loo l5(5);
l5.show();
Loo::show_();
return 0;
}
And the output I get is:
x 0, y 0, z 0
a 1, b 1, c 2
x 1, y 1, z 1
a 1, b 7, c 7
x 1, y 1, z 1
The first two lines are unspectactular: they show what can be expected from the code. The third line is also unsurprising. Importantly, it shows that the member initialization of b was invoked by the default constructor (y=1). The fourth line however is very odd: It starts with a=1. How? Let's take apart the commonly known rules on initilization order: the initializer list gets processed left to right for all virtual base classes, than all base classes, then all members. We only have members, so initialization order is a, then b, then c. Next, according to this site Non-static data members - cppreference.com[^] the non-static member initialization of b gets skipped, because b is on the initalizer list. This means, b is not initialized at all by the time a is getting initialized! Note that y remains unchanged, proving that the member initializer is not invoked! Therefore the value assigned to a is undefined. As it seems, in this case b assumes a value of 0, incremented to 1, and then assigned to a. Next, b gets initialized. It's value is based on i, which is 5, so the value of b should be 6. The output shows 7 - but let's look further: we still have to initialize c, which again is based b, incrementing it. There