Reputation: 337
I can't understand the output of this code. I expect 10
to be printed, but the output is 85
. Can someone explain what's happening?
#include <iostream>
using namespace std;
class A
{
public:
int x=3;
A(int a) : x(a) {}
};
class B: public A
{
public:
int y = 10;
B() : A(y) {}
};
int main()
{
B b;
cout << b.x << endl;
return 0;
}
But, changing it to:
class B: public A
{
public:
int y = 10;
B(int s) : A(s) {}
};
int main()
{
B b(4);
cout << b.x << endl;
return 0;
}
It works as expected (prints 4).
Upvotes: 7
Views: 1492
Reputation: 337
As suggested by the link in @Someprogrammerdude's comment:
The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:
Upvotes: 0
Reputation: 312
Because of initialization order rules in first case you call A() constructor before y was assigned to 10, so value of y is undefined and depends on current value of those sizeof(int) bytes in the stack. So you initialize x with that undefined semi-random value and print it later. In second case you call B(int) with s = 4 and it successfully initializes x with 4.
Upvotes: 2
Reputation: 118340
This is called "undefined behavior".
Base classes are constructed first, before the class members are constructed.
In this case, you're passing the contents of an uninitialized class member to the base class's constructor.
Just because you have an initialization statement for the class member that appears on a previous line, in the .cpp
file, doesn't mean that this is the initialization order. C++ does not always work this way. You're passing an uninitialized y
to the base class's constructor, and then when the base class returns the subclass gets constructed, setting y
to what it's initialized to.
Upvotes: 6