Reputation: 1063
In the code below i'm assigning a value to uninitialized class member upon creation of a base class. Why didn't this cause runtime error?
class Foo {
public:
Foo(std::string) {}
};
class Bar : public Foo {
public:
Bar() : Foo(s = f()) {} // assigning to uninitialized class member
void print() {
std::cout << s << std::endl;
}
std::string f() {
return "Some string";
}
private:
std::string s;
};
int main()
{
Bar b;
b.print();
return 0;
}
But adding another one member to the class Bar produces an error on creation of the Foo class:
Class Bar {
// same as above
private:
std::string s;
int a; // adding another member
};
Why do this happens?
Upvotes: 0
Views: 198
Reputation:
Base class and class members are initialized in order of declaration (virtual base classes are different):
The order at initialization in a constructor does not change it.
In your case Foo is uninitialized, hence Bar and it's members - undefined behaviour (s has some rubbish data while assigning to it).
Upvotes: 0
Reputation: 320371
"Runtime error"? There's no "runtime error" when assigning to an uninitialized member. In C++ the state of "being uninitialized" is not detectable at run-time, which is why it cannot possibly be handled in any deterministic manner (like with "runtime error").
When you do something like that, your code exhibits undefined behavior. The away this undefined behavior will manifest itself is unpredictable. It can easily be sensitive to completely unrelated factors, like declaring another member in the class. That's all there is to it.
Upvotes: 1
Reputation: 3379
I tried to debug your code. It seems that, when you write:
Bar() : Foo(s = f()) {}
The s
object is not properly created yet. Because constructor call of Foo()
is not complete yet. Basically it is in a undefined state. So any behaviour will be undefined.
But this code behaviour is not undefined:
Bar() : Foo(/*anything*/) {
s = f();
}
Because the constructor call is complete.
Note: I tested in msvc11
Upvotes: 0
Reputation: 6505
When f() executes the class Bar is uninitialized so the member 'a' has no value. It's interesting that this code runs in visual studio 2008 but in any case this is not safe to do.
Razvan.
Upvotes: 0